Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
查找MongoDB中包含数组字段的文档是查询数组的子集_Mongodb - Fatal编程技术网

查找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中进行一些聚合。我从我的答案中删除了旧的低效聚合,因为它更加优雅,并且现在已经可用了一段时间。