Haw*_*ngs 2 mongodb mongodb-query aggregation-framework
我在运行时创建的内存中有一个数组A,另一个数组B保存在mongo数据库中.如何有效地从A中获取不在B中的所有元素?
您可以假设存储在mongodb中的数组比运行时创建的数组大几个数量级,因此我认为从mongo获取完整数组并计算结果效率不高,但我没有找到任何查询在mongo中操作,允许我计算我想要的结果.
请注意,$ nin运算符与我想要的相反,即它从B中检索不在A中的元素.
例:
在运行时在我的应用程序中创建的数组A是[2, 3, 4].
存储在mongodb中的数组B是[1, 3, 5, 6, 7, 10].
我期望的结果是[2, 4].
唯一的事情反应即"修改"的文件是.aggregate()和.mapReduce(),其中前者是更好的选择.
在这种情况下,您要求$setDifference比较"集合"并返回两者之间的"差异".
所以用你的数组表示一个文档:
db.collection.insert({ "b": [1, 3, 5, 6, 7, 10] })
Run Code Online (Sandbox Code Playgroud)
运行聚合:
db.collection.aggregate([{ "$project": { "c": { "$setDifference": [ [2,3,4], "$b" ] } } }])
Run Code Online (Sandbox Code Playgroud)
哪个回报:
{ "_id" : ObjectId("596005eace45be96e2cb221b"), "c" : [ 2, 4 ] }
Run Code Online (Sandbox Code Playgroud)
如果你不想要的"套",而是要提供一个数组一样[2,3,4,4],那么你可以去比较$filter和$in相反,如果你有MongoDB的3.4至少包括:
db.collection.aggregate([
{ "$project": {
"c": {
"$filter": {
"input": [2,3,4,4],
"as": "a",
"cond": {
"$not": { "$in": [ "$$a", "$b" ] }
}
}
}
}}
])
Run Code Online (Sandbox Code Playgroud)
或$filter与$anyElementTrue早期版本:
db.collection.aggregate([
{ "$project": {
"c": {
"$filter": {
"input": [2,3,4,4],
"as": "a",
"cond": {
"$not": {
"$anyElementTrue": {
"$map": {
"input": "$b",
"as": "b",
"in": {
"$eq": [ "$$a", "$$b" ]
}
}
}
}
}
}
}
}}
])
Run Code Online (Sandbox Code Playgroud)
两者都会返回:
{ "_id" : ObjectId("596005eace45be96e2cb221b"), "c" : [ 2, 4, 4 ] }
Run Code Online (Sandbox Code Playgroud)
这当然是"不是一组",因为它4被作为输入"两次"提供,因此也返回"两次".