MongoDB:根据文档中的另一个属性从数组中选择元素 [英] MongoDB: Select element from array based on another property in the document

查看:181
本文介绍了MongoDB:根据文档中的另一个属性从数组中选择元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个MongoDB集合,其中包含以下结构的文档(省略了无趣的部分):

I have a MongoDB collection with documents of the following structure (non-interesting bits left out):

{
  displayFieldId: "abcd",
  fields: [
    {
      fieldId: "efgh",
      value: "cake"
    },
    {
      fieldId: "abcd",
      value: "cheese"
    },
    ....
  ],
  ....
}

我想对此集合运行查询,以仅获取fields数组中与文档的displayFieldId匹配的fields数组中的元素.因此,对以上文档的查询结果应为:

I would like to run a query on this collection to fetch only the element in the fields array which fieldId matches the document's displayFieldId. The result of the query on the document above should thus be:

{
  fields: [
    {
      fieldId: "abcd",
      value: "cheese"
    }
  ],
  ....
}

我构造了以下查询.它符合我的要求,但displayFieldValue是硬编码的

I constructed the following query. It does what I want, with the exception that the displayFieldValue is hard coded

db.containers.find({}, {
  fields: {
    $elemMatch: {
      fieldId: "abcd"
    }
  }
});

有没有办法让它查看文档的displayFieldId并使用该值而不是硬编码的"abcd"?

Is there a way to make it look at the document's displayFieldId and use that value instead of the hard coded "abcd"?

服务器正在运行MongoDB 3.2.6

The server is running MongoDB 3.2.6

如果可能的话,我想在不进行聚合的情况下执行此操作,但是如果无法完成,则必须进行聚合

If possible, I would like to do this without aggregation, but if that can't be done, then aggregation will have to do

推荐答案

使用聚合框架:

db.containers.aggregate([
    {        
        "$redact": { 
            "$cond": [
                { 
                    "$anyElementTrue": [ 
                        {
                            "$map": {
                                "input": "$fields",
                                "as": "el",
                                "in": { 
                                    "$eq": ["$$el.fieldId", "$displayFieldId"]
                                }
                            }
                        }
                    ] 
                },
                "$$KEEP",
                "$$PRUNE"
            ]
        }
    },
    {
        "$project": {
            "displayFieldId": 1,
            "fields": {
                "$filter": {
                    "input": "$fields",
                    "as": "el",
                    "cond": {
                        "$eq": ["$$el.fieldId", "$displayFieldId"]
                    }
                }
            },
            "otherfields": 1,
            ....
        }
    }
])


MongoDB 3.4 :

db.containers.aggregate([
    {        
        "$redact": { 
            "$cond": [
                { 
                    "$anyElementTrue": [ 
                        {
                            "$map": {
                                "input": "$fields",
                                "as": "el",
                                "in": { 
                                    "$eq": ["$$el.fieldId", "$displayFieldId"]
                                }
                            }
                        }
                    ] 
                },
                "$$KEEP",
                "$$PRUNE"
            ]
        }
    },
    {
        "$addFields": {
            "fields": {
                "$filter": {
                    "input": "$fields",
                    "as": "el",
                    "cond": {
                        "$eq": ["$$el.fieldId", "$displayFieldId"]
                    }
                }
            }
        }
    }
])


没有聚合框架-使用 $where (慢速查询):


Without aggregation framework - using $where (the slow query):

db.containers.find({
    "$where": function() {
        var self = this;
        return this.fields.filter(function(f){
            return self.displayFieldId === f.fieldId;
        }).length > 0;
    }
}).map(function(doc){
    var obj = doc;
    obj.fields = obj.fields.filter(function(f){
        return obj.displayFieldId === f.fieldId;
    });
    return obj;
})

这篇关于MongoDB:根据文档中的另一个属性从数组中选择元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆