在MongoDB中查找文档,其中数组字段是查询数组的子集

时间:2013-04-19 16:31:47

标签: mongodb

假设我插入了一组文档,每个文档都有一个array字段。我想找到所有文档,使其array字段是查询数组的子集。例如,如果我有以下文件,

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']}),我希望文档onethree看作['a', 'b', 'c']['b', 'c']都是['a', 'b', 'c']的子集。换句话说,我想做Mongo的$all查询的反转,该查询选择所有文档,使得查询数组是文档的array字段的子集。这可能吗?如果是的话,怎么样?

3 个答案:

答案 0 :(得分:9)

使用聚合框架或查找查询有一种简单的方法。

查找查询很简单,但您必须使用$ elemMatch运算符:

> db.collection.find({array:{$not:{$elemMatch:{$nin:['a','b','c']}}}}, {_id:0,name:1})

注意,这表明我们想要不匹配具有(同时)不等于'a','b'或'c'的元素的数组。我添加了一个投影,它只返回结果文档的名称字段,这是可选的。

答案 1 :(得分:9)

在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"

答案 2 :(得分:2)

要在聚合环境中执行此操作,您可以使用$setIsSubset

db.collection.aggregate([
    // Project the original doc and a new field that indicates if array
    // is a subset of ['a', 'b', 'c']
    {$project: {
        doc: '$$ROOT',
        isSubset: {$setIsSubset: ['$array', ['a', 'b', 'c']]}
    }},
    // Filter on isSubset
    {$match: {isSubset: true}},
    // Project just the original docs
    {$project: {_id: 0, doc: 1}}
])

请注意,MongoDB 2.6中添加了$setIsSubset