我正在尝试使用mongodb聚合查询来连接($lookup)两个集合,然后统计连接数组中所有唯一值的不同数量。*注意:我不一定知道metaDataMap数组中有哪些字段(key)。而且我不想计算或包含可能存在于Map中也可能不存在的字段。所以这就是为什么聚合查询看起来像这样的原因。
那么我的两个集合长这样:events-
我目前有以下内容: ```
那么我的两个集合长这样:events-
{
"_id" : "1",
"name" : "event1",
"objectsIds" : [ "1", "2", "3" ],
}
对象
{
"_id" : "1",
"name" : "object1",
"metaDataMap" : {
"SOURCE" : ["ABC", "DEF"],
"DESTINATION" : ["XYZ", "PDQ"],
"TYPE" : []
}
},
{
"_id" : "2",
"name" : "object2",
"metaDataMap" : {
"SOURCE" : ["RST", "LNE"],
"TYPE" : ["text"]
}
},
{
"_id" : "3",
"name" : "object3",
"metaDataMap" : {
"SOURCE" : ["NOP"],
"DESTINATION" : ["PHI", "NYC"],
"TYPE" : ["video"]
}
}
我的结果是
{
_id:"SOURCE", count:5
_id:"DESTINATION", count: 4
_id:"TYPE", count: 2
}
我目前有以下内容: ```
这是我目前的进展:
```db.events.aggregate([
{$match: {"_id" : id}}
,{$lookup: {"from" : "objects",
"localField" : "objectsIds",
"foreignField" : "_id",
"as" : "objectResults"}}
,{$unwind: "$objectResults"} //Line 1
,{$project: {x: "$objectResults.metaDataMap"}} //Line 2
,{$unwind: "$x"}
,{$project: {"_id":0}}
,{$project: {x: {$objectToArray: "$x"}}}
,{$unwind: "$x"}
,{$group: {_id: "$x.k", tmp: {$push: "$x.v"}}}
,{$addFields: {tmp: {$reduce:{
input: "$tmp",
initialValue:[],
in:{$concatArrays: [ "$$value", "$$this"]}
}}
}}
,{$unwind: "$tmp"}
,{$group: {_id: "$_id", uniqueVals: {$addToSet: "$tmp"}}}
,{$addFields: {count: {"$size":"$uniqueVals"}}}
,{$project: {_id: "$_id", count: "$count"}}
]);
我的问题在于我标记的1&2两行。上面的方法虽然可行,但是处理25,000个metaDataMap数组字段(objectsResults.metaDataMap)需要大约50秒的时间。例如,在对象1的metaDataMap SOURCE数组中有25,000个值。这太慢了。我另外一个更快的方法是用以下代码替换1&2两行:
,{$project: {x: "$objectResults.metaDataMap"}} //Line 1
,{$unwind: "$x"} //Line 2
这种方法速度很快(不到3秒),但只能在包含大约10,000个项目或更少的数据集上运行。如果超过这个数量,我会收到一个“超过最大文档大小”的错误。
请帮帮我!
metaDataMap
结构更改为"metaDataMap" : ["k":{ "SOURCE", "v" : [ "ABC", "DEF" ]}...]
并在$lookup
后插入$map
阶段。类似于{"$project": {"data":{"$map": {"input":"$objectResults.metaDataMap","as": "resultom","in": {"$map": {"input": "$$resultom","as": "resultim","in": {"k":"$$resultim.k","v":{ "$size": "$$resultim.v"}}}}} }}}
。我相信这样你就可以得到大小,展开应该会更快。 - s7vr