Mongodb 计算mongo聚合(pymongo)中的记录类型
我正在使用pymongo进行以下聚合(Mongodb 计算mongo聚合(pymongo)中的记录类型,mongodb,pymongo,mongodb-query,aggregation-framework,Mongodb,Pymongo,Mongodb Query,Aggregation Framework,我正在使用pymongo进行以下聚合(users以前定义为我要查询的用户列表): 这给了我以下结果: {u'ok': 1.0, u'result': [{u'_id': u'user22', u'badges': [u'gold', u'silver', u'silver']}, {u'_id': u'user2', u'badges': [u'gold', u'gold']}, {u'
users
以前定义为我要查询的用户列表):
这给了我以下结果:
{u'ok': 1.0,
u'result': [{u'_id': u'user22',
u'badges': [u'gold', u'silver', u'silver']},
{u'_id': u'user2',
u'badges': [u'gold', u'gold']},
{u'_id': u'user15',
u'badges': [u'gold', u'bronze', u'bronze']},
{u'_id': u'user11',
u'badges': [u'gold']},
{u'_id': u'user3',
u'badges': [u'silver', u'bronze']},
{u'_id': u'user18',
u'badges': [u'bronze']}
]
}
这没关系,但我真正想得到的是每种奖牌类型的计数(类型=金/银/铜)。我可以在Python的后处理中轻松做到这一点,但我觉得我应该能够在相同的管道中做到这一点,我想学习“如何更好地使用mongo”:
所以说得清楚一点,我真正想要的是(我手工生成了这个理想的输出,因此可能与上面的数据不一致或语法错误,但我认为这能说明问题):
我的数据结构要求并不严格。我也很乐意使用金/银/铜作为键,并避免使用嵌套的dict:
{u'_id': u'user22',
u'gold': 1, u'silver': 2},
{u'_id': u'user2',
u'gold': 2},
...
我试着用$sum
操作符做了很多事情,但是运气不好。当我尝试动态生成字段名时,我得到:
失败:异常:组聚合字段名“$badge”不能是操作员名
有什么想法吗?提前谢谢
(还有,半相关的…我对map reduce不太了解。也许这是一个候选。我开始使用聚合,到目前为止它们对我很有效。我可能也应该了解map reduce)除了将徽章推送到数组之外,你还可以做些什么,取决于徽章类型。这通常通过测试操作员内部的条件来完成,以确定“总和”的贡献量:
collection.aggregate([
{“$match”:{“user”:{“$in”:users}}},
{“$组”:{
“_id”:“$user”,
“黄金”:{
“$sum”:{
“$cond”:[
{“$eq”:[“$badge”,“gold”]},
1.
0
]
}
},
“银”:{
“$sum”:{
“$cond”:[
{“$eq”:[“$badge”,“silver”]},
1.
0
]
}
},
“青铜”:{
“$sum”:{
“$cond”:[
{“$eq”:[“$badge”,“Brown”]},
1.
0
]
}
}
}}
])
这将正确地将每个类型相加,当然每个用户都会有一个“金/银/铜”计数,不管它是否大于0。您不能在聚合框架中“动态”创建字段
如果您真的需要“动态”字段,那么您唯一的选择就是mapReduce,但这当然不会像聚合框架那样高效。条件和确实为您提供了最佳选择。感谢@neil lunn的更新。现在,我看到了您如何在其中添加
$cond
,看起来我缺少了第一个参数周围的大括号-我仍然习惯于所有的标点符号。
{u'ok': 1.0,
u'result': [{u'_id': u'user22',
u'badges': {u'gold': 1, u'silver': 2}},
{u'_id': u'user2',
u'badges': {u'gold': 2}},
{u'_id': u'user15',
u'badges': {u'gold': 1, u'bronze': 2}},
{u'_id': u'user11',
u'badges': {u'gold': 1}},
{u'_id': u'user3',
u'badges': {u'silver': 1, u'bronze': 1}},
{u'_id': u'user18',
u'badges': {u'bronze': 1}}
]
}
{u'_id': u'user22',
u'gold': 1, u'silver': 2},
{u'_id': u'user2',
u'gold': 2},
...