我有两个系列:
会议记录:
{
"_id": {
"$oid": "638d07005bdfe572e95b9282"
},
"key": "reference/genetic/2015",
"editor": [
"Amir Hossein Gandomi",
"Amir Hossein Alavi",
"Conor Ryan"
],
"title": "Handbook of Genetic Programming Applications",
"booktitle": {
"$numberDouble": "NaN"
},
"publisher": "Springer",
"volume": {
"$numberDouble": "NaN"
},
"year": "2015"
}
在诉讼中:
{
"_id": {
"$oid": "638d06b85bdfe572e92b7567"
},
"key": "conf/coopis/ChenD00",
"author": [
"Qiming Chen",
"Umeshwar Dayal"
],
"title": "Multi-Agent Cooperative Transactions for E-Commerce.",
"pages": "311-322",
"year": "2000",
"booktitle": "CoopIS"
}
我需要计算一个人在前面的集合中作为编辑出现的次数,并将其与他们的名字在后面的集合中作为作者出现的次数相加。
这就是我所拥有的:
m6 = proceeding_collection.aggregate([
{
"$unwind": "$editor"
},
{
"$match": {
"editor": { "$ne": numpy.NaN }
}
},
{
"$group": {
"_id": "$editor",
"count": { "$sum": 1 }
}
},
{
"$lookup": {
"from": "inproceedings",
"let": {"editor": "$_id"},
"pipeline":
[
{
"$unwind": "$author"
},
{
"$match":
{
"$expr": {
"$in":
["$$editor", ["$author"]]
}
}
},
],
"as": "inproceedings"
}
},
{
"$project": {
"_id": 1,
"count": 1,
"inproceedings_count": { "$size": "$inproceedings" }
}
},
{
"$addFields": {
"total_count": { "$sum": ["$count", "$inproceedings_count"] }
}
},
{
"$sort": {
"total_count": -1
}
},
{
"$limit": 10
}
])
for doc in m6:
print(doc)
第一部分工作得很好,"editor"
字段可以是数组或单个字符串值,但外部集合中的"author"
字段也是如此。因此,我尝试在管道中展开数组,并基于编辑器名称进行匹配,但在进程中计数始终为零。
1条答案
按热度按时间brjng4g31#
当你在执行单条件绝对连接时,你可以使用
$lookup
的简单版本。https://mongoplayground.net/p/pRM-sbQwSp4其他协助:
我使用
mgodatagen
生成了3 M个会议记录和50 k个会议记录,并在author
上添加了一个索引。(我在editor
上添加索引是错误的,如果你想做一个初始的$project
,它不会加速任何事情。无论如何,mgodatagen在这里:而且它创建了你所拥有的记录数量(3 M,50 K)。注意作者索引。
运行前面给定的带有explain的查询将显示:
记录如下:
因此,我认为
2.5 seconds
对于这种类型的查询对于3 M记录来说还不错。最后一个更新,我在想,你根本不需要连接。
通过在两个集合上设置
editor
和author
索引,任何小的匹配或过滤都将非常快,即使是3 M条记录。(分别针对编辑和作者),它会一直使用索引。您可以在应用程序代码中对总数求和。类似于:对我来说,它以
1032ms
的速度运行。几乎快了2.5倍。