查找MongoDB中包含数组字段的文档是查询数组的子集
假设我有一个插入一组文档,每个文档都有一个查找MongoDB中包含数组字段的文档是查询数组的子集,mongodb,Mongodb,假设我有一个插入一组文档,每个文档都有一个数组字段。我希望查找所有文档,使其数组字段是查询数组的子集。例如,如果我有以下文档 collection.insert([ { 'name': 'one', 'array': ['a', 'b', 'c'] }, { 'name': 'two', 'array': ['b', 'c', 'd'] }, { 'name': 'three', 'array': ['b', 'c'
数组
字段。我希望查找所有文档,使其数组
字段是查询数组的子集。例如,如果我有以下文档
collection.insert([
{
'name': 'one',
'array': ['a', 'b', 'c']
},
{
'name': 'two',
'array': ['b', 'c', 'd']
},
{
'name': 'three',
'array': ['b', 'c']
}
])
我查询
collection.find({'array':{'superset':['a','b','c']})
,我希望看到文档1
和3
,因为['a','b','c']
和['b','c']
都是['a','b','c']
。换句话说,我想做Mongo的$all
查询的相反操作,它选择所有文档,使查询数组成为文档数组
字段的子集。这可能吗?如果可能,如何做?有一种简单的方法可以使用聚合框架或查找查询来实现这一点
查找查询很简单,但必须使用$elemMatch运算符:
> db.collection.find({array:{$not:{$elemMatch:{$nin:['a','b','c']}}}}, {_id:0,name:1})
请注意,这表示我们不希望匹配(同时)元素不等于“a”、“b”或“c”的数组。我添加了一个投影,它只返回结果文档的名称字段,这是可选的。在MongoDb中,对于数组字段:
"$in:[...]" means "intersection" or "any element in",
"$all:[...]" means "subset" or "contain",
"$elemMatch:{...}" means "any element match"
"$not:{$elemMatch:{$nin:[...]}}" means "superset" or "in"
要在聚合上下文中执行此操作,可以使用:
db.collection.aggregate([
//投影原始文档和一个新字段,该字段指示
//是['a','b','c'的子集
{$项目:{
文档:“$$ROOT”,
isSubset:{$setIsSubset:['$array',['a','b','c']}
}},
//isSubset上的过滤器
{$match:{isSubset:true}},
//项目只是原始文档
{$project:{{u id:0,doc:1}}
])
请注意,
$setIsSubset
是在MongoDB 2.6中添加的。您需要在IMHO.nice中进行一些聚合。我从我的答案中删除了旧的低效聚合,因为它更加优雅,并且现在已经可用了一段时间。