我有集合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在,但我需要两个,并按照确切的顺序。
这可能吗?
答案 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
数组中没有元素满足条件A
和B
中的至少一个的文档。因此,它会找到文档1,但不会找到文档2(其中"nids" : [ 0, 5 ]
不满足条件B
。
请注意,{ $ne: 10 }
相当于{ $nin: [10] }
。