9

假设我有一个插入一组文档,每个文档都有一个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']}),我希望看到文档onethreeas['a', 'b', 'c']并且['b', 'c']都是['a', 'b', 'c']. 换句话说,我想做 Mongo$all查询的逆操作,它选择所有文档,使得查询数组是文档array字段的子集。这可能吗?如果是这样,如何?

4

3 回答 3

11

在 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"
于 2014-03-27T03:10:44.167 回答
10

有一种简单的方法可以使用聚合框架或查找查询来执行此操作。

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

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

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

于 2013-04-19T19:04:16.540 回答
4

要在聚合上下文中执行此操作,您可以使用$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}}
])

请注意,这$setIsSubset是在 MongoDB 2.6 中添加的。

于 2015-06-16T17:55:05.093 回答