0

我的数据库中有一个集合,其中大多数文档都有一个数组字段。这些数组正好包含2 个元素。现在我想找到所有这些数组元素都是我的查询数组元素的所有文档。

示例文件:

{ a:["1","2"] },
{ a:["2","3"] },
{ a:["1","3"] },
{ a:["1","4"] }

查询数组:

["1","2","3"]

查询应该找到前 3 个文档,但不是最后一个,因为我的查询数组中没有“4”。

预期结果:

{ a:["1","2"] },
{ a:["2","3"] },
{ a:["1","3"] }

期待一个有用的答案:)。

4

3 回答 3

3

由于大小是静态的,您只需检查两个元素是否都在 [1,2,3] 中;

db.test.find(
  { $and: [ { "a.0": {$in: ["1","2","3"] } },
            { "a.1": {$in: ["1","2","3"] } } ] },
  { _id: 0, a: 1 }
)

>>> { "a" : [ "1", "2" ] }
>>> { "a" : [ "2", "3" ] }
>>> { "a" : [ "1", "3" ] }

编辑:动态做有点毛茸茸,我想不出没有聚合框架的方法。只需将匹配项计为 0,将不匹配项计为 1,最后删除所有总和为 != 0 的组;

db.test.aggregate(
  { $unwind: "$a" },
  { $group: { _id: "$_id", 
              a: { $push: "$a" },
              fail: { $sum: {$cond: { if: { $or: [ { $eq:["$a", "1"] },
                                                   { $eq:["$a", "2"] },
                                                   { $eq:["$a", "3"] }]
                                          },
                                      then: 0,
                                      else: 1 } } } } },
  { $match: { fail: 0 } },
  { $project:{ _id: 0, a: 1 } } 
)

>>> { "a" : [ "1", "3" ] }
>>> { "a" : [ "2", "3" ] }
>>> { "a" : [ "1", "2" ] }
于 2014-06-18T18:54:16.647 回答
2

我还认为,没有聚合框架是不可能的(如果元素计数是动态的)。但我发现了更通用的方法:

db.tests.aggregate({
  $redact: {
    $cond: {
      if: {$eq: [ {$setIsSubset: [ '$a', [ "1", "2", "3" ] ]}]},
      then: '$$KEEP',
      else: '$$PRUNE'
    }
  }
})
于 2016-09-10T09:30:12.850 回答
0

我相信您的问题的答案是使用

$in

(来自文档:)

考虑以下示例:

db.inventory.find( { 数量: { $in: [ 5, 15 ] } } )

此查询选择清单集合中 qty 字段值为 5 或 15 的所有文档。虽然您可以使用 $or 运算符表达此查询,但在对相同的执行相等性检查时选择 $in 运算符而不是 $or 运算符场地。

您还可以使用数组做更复杂的事情。结帐: http ://docs.mongodb.org/manual/reference/operator/query/in/

于 2014-06-18T18:25:37.223 回答