查找包含MongoDB中特定文档的数组的文档

时间:2016-08-05 08:58:16

标签: arrays mongodb mongodb-query

我有集合path_test,里面有2个文件

文件1

{
  "_id" : 1,
  "tpc" : 5,
  "path" : [ 
    {
      "nids" : [ 0, 10, 11 ],
      "ctc" : 2
    }, 
    {
      "nids" : [ 0, 10 ],
      "ctc" : 2
    }, 
    {
      "nids" : [ 0, 10, 21 ],
      "ctc" : 1
    }
  ]
}

文件2

{
  "_id" : 2,
  "tpc" : 5,
  "path" : [ 
    {
      "nids" : [ 0, 10, 110 ],
      "ctc" : 1
    }, 
    {
      "nids" : [ 0, 10, 11 ],
       "ctc" : 2
    }, 
    {
      "nids" : [ 0, 5 ],
      "ctc" : 2
    }
  ]
}

我想要获得的结果是包含path数组的文档,其中所有元素都有nids [0, 10, *]。订单很重要,因此[10, 0, *]会出错。 它应该找到文档1,但不是文档2.在开始使用map-reduce或聚合之前,希望我能用查询解决这个问题。

这是我到目前为止所尝试的

查询1

db.getCollection('path_test').find( {
  "path": { $not: { $elemMatch: { "nids.0": { $nin: [0] }, "nids.1": { $nin: [10] } } } }
});

查询2

db.getCollection('path_test').find( {
  "path.nids": { $not: { $elemMatch: { $nin: [0, 10] } } }
});

但两个查询都给我结果,其中只有0在或只有10在,但我需要两个,并按照确切的顺序。

这可能吗?

1 个答案:

答案 0 :(得分:2)

  

至少没有一个意味着没人

查询1

为简化起见,我们分配

A = "nids.0": { $ne: 0 }
B = "nids.1": { $ne: 10 }
C = { A, B }

然后

{ "path" : { $elemMatch: C } }

将找到path数组中至少有一个元素满足条件C的文档,而

{ "path" : { $not: { $elemMatch: C } } }

将查找path数组中没有满足条件C的元素的文档。

文档1和文档2在path数组中没有满足条件C的元素,因此Query1输出包含它们。如果,例如,您添加到文档1的path数组

{ "nids": [ 1, 11, 110], "ctc" : 1 }

然后,文档1将不在查询1的输出中,因为此添加的元素满足C

查询2

为简化起见,我们分配

C = { $nin: [0, 10] }

然后

{ "path.nids" : { $not: { $elemMatch: C } } }

将查找path.nids数组中没有满足条件C的元素的文档。

path.nids数组中的文档1和文档2具有满足条件C的元素,因此查询2输出不包含它们。如果,例如,您添加到收集文档

{ "_id" : 6, "tpc" : 5, "path" : [ { "nids" : [ 0, 10 ], "ctc" : 1 } ] }

然后它将出现在查询2的输出中,因为在path.nids数组中没有满足C的元素。

<强>解决方案

在查询1中替换

{ $elemMatch: { "nids.0": { $nin: [0] }, "nids.1": { $nin: [10] } } }

{ $elemMatch: { $or: [ { "nids.0": { $ne: 0 } }, { "nids.1": { $ne: 10 } } ] } }

此新查询将查找path数组中没有元素满足条件AB中的至少一个的文档。因此,它会找到文档1,但不会找到文档2(其中"nids" : [ 0, 5 ]不满足条件B

请注意,{ $ne: 10 }相当于{ $nin: [10] }