我搜索了一下,但是找不到使用MongoDB的方法 - 或者我只是误解了$ all和$ in运算符。
如果我有以下文件:
{
arr : ["foo","bar","baz"]
},
{
arr : ["bar","foo"]
},
{
arr : ["foo"]
}
我想要一个返回最后两个文档的查询。基本上任何文档只包含["foo", "bar"]
的任意组合,但不包含任何其他项目。这是排除方面,我无法弄清楚 - 基本上对于给定的数组,只返回arr
字段仅包含该数组中的元素的文档。
> db.foo.find({arr : {"$in" : ["foo", "bar"]}})
{ "_id" : ObjectId("532a0ff6907560a1e88a2c0a"), "arr" : [ "foo", "bar", "baz" ] }
{ "_id" : ObjectId("532a0ffc907560a1e88a2c0b"), "arr" : [ "foo", "bar" ] }
{ "_id" : ObjectId("532a0ffe907560a1e88a2c0c"), "arr" : [ "foo" ] }
> db.foo.find({arr : {"$all" : ["foo", "bar"]}})
{ "_id" : ObjectId("532a0ff6907560a1e88a2c0a"), "arr" : [ "foo", "bar", "baz" ] }
{ "_id" : ObjectId("532a0ffc907560a1e88a2c0b"), "arr" : [ "foo", "bar" ] }
>
这甚至可能吗?我不知道在查询时哪些值是排他性的。
答案 0 :(得分:4)
您可以通过组合多个运算符来实现此目的:
db.foo.find({arr: {$not: {$elemMatch: {$nin: ['foo', 'bar']}}}})
$elemMatch
$nin
找到了单个arr
元素既不是'foo'也不是'bar'的文档,然后父$not
反转了匹配以返回与任何元素不匹配的所有文档。
但是,这也会返回arr
缺失或没有元素的文档。要在限定符中排除$and
所需的内容,以确保arr
至少包含一个元素:
db.foo.find({$and: [
{arr: {$not: {$elemMatch: {$nin: ['foo', 'bar']}}}},
{'arr.0': {$exists: true}}
]})
答案 1 :(得分:1)
您可以使用aggregation framework来实现您的目标。查询将类似于:
db.collection.aggregate([
{$unwind:"$arr"},
{$group:{
_id:"$_id",
// If arr is "foo" or "bar", add 0 to the sum else add 1 to the sum
exclude:{$sum:{$cond:[{$or:[{$eq:["$arr","foo"]},{$eq:["$arr","bar"]}]},0,1]}}}},
// Exclude all documents where "exclude" count is non-zero
{$match:{exclude:0}}
])