查找包含包含具有特定字段的文档的数组的文档 [英] Find documents with arrays that contain a document with a particular field

查看:70
本文介绍了查找包含包含具有特定字段的文档的数组的文档的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只想查找数组中包含所有'docs.foo'的文档. 在我的示例中,我应该只得到_id: 2结果:

I want to find only documents that have all 'docs.foo' present in a array. In my example I should get only _id: 2 result:

{  
    _id : 1,
    docs : [
        { bar : 2},
        { foo : 3, bar : 3}
    ]
},
{  
    _id : 2,
    docs : [
        { foo : 2, bar : 2},
        { foo : 3, bar : 3}
    ]
}

我想到了类似的东西

db.collection.find({'docs.foo': {$nin: [$exists: false]}})

但无法使其正常工作.

推荐答案

使用 $where 运算符.

Using the $where operator.

db.collection.find(function() { 
    return this.docs.length === this.docs.filter(function(doc) {
        return typeof(doc.foo) !== "undefined" && doc.foo !== null ;}).length 
})


执行此操作的另一种方法是运行两个查询:一个使用_id .2/reference/method/db.collection.distinct/#db.collection.distinct"rel =" nofollow> distinct() 方法:


Another way to do this is to run two queries: One to retrieve the _id of all those documents that don't match your criteria using the distinct() method:

var unwantedIds = db.collection.distinct( "_id", { "docs": { "$elemMatch": { "foo": { "$exists": false } } } } );

然后使用$nin运算符返回所有符合您条件的文档.

Then use the $nin operator to return all those documents that match your criteria.

db.collection.find({ "_id": { "$nin": unwantedIds } } )


您还可以使用 .aggregate() 方法,但这仅在使用3.2或更高版本时有效,因为您需要使用


You can also use the .aggregate() method but this only work if you are on version 3.2 or newer because you need to use the $filter

第一阶段是 $match 阶段在其中过滤掉缺少"foo"字段的那些文档.这减少了将在管道中处理的文档总数.下一个也是最后一个阶段是 $redact 阶段.在此阶段,您需要使用$size运算符返回"docs"字段的大小以及存在"foo"的子文档数组的大小,并返回所有两个值都在其中的文档相等.

First stage in the pipeline is the $match stage where you filter out those documents where the "foo" field is absent. This reduce the total number of documents that will be processed down the pipe. The next and last stage is the $redact stage. In this stage you need to use the $size operator to return the size of the the "docs" field and the size of the array of the sub-documents in where "foo" is present and return all those documents where the two values are equals.

db.collection.aggregate([
    { "$match": { "docs.foo": { "$exists": true } } }, 
    { "$redact": { 
        "$cond": [ 
            { "$eq": [ 
                { "$size": "$docs" }, 
                { "$size":  { 
                    "$filter": { 
                        "input": "$docs", 
                        "as": "doc", 
                        "cond": { 
                            "$ne": [ 
                                { "$ifNull": [ "$$doc.foo", null ] },
                                null 
                            ] 
                        } 
                    }
                }}
            ]}, 
            "$$KEEP", 
            "$$PRUNE"
        ]
    }}
])

这篇关于查找包含包含具有特定字段的文档的数组的文档的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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