使用OrderedDict时,“管道阶段规范对象必须包含一个字段”

时间:2014-04-16 14:22:38

标签: mongodb pymongo

我尝试运行聚合命令:

request = collections.OrderedDict([
        ("$unwind", "$tags" ),
        ("$group", { "_id" : "$tags" , "count" : { "$sum" : 1 }  } ),
        ("$project", { "_id" : 0, "tag" : "$_id" , "count" : 1 } ),
        ("$sort", { "count" : -1 } ),
        ("$limit", 3 )])

print client.devoxx.talks.aggregate(request)

但MongoDB拒绝它:

pymongo.errors.OperationFailure: command SON([('aggregate', u'talks'), ('pipeline', [OrderedDict([('$unwind', '$tags'), ('$group', {'count': {'$sum': 1}, '_id': '$tags'}), ('$project', {'count': 1, '_id': 0, 'tag': '$_id'}), ('$sort', {'count': -1}), ('$limit', 3)])])]) failed: exception: A pipeline stage specification object must contain exactly one field.

在我看来,我在订购字典的一个项目中有每个聚合阶段。

1 个答案:

答案 0 :(得分:12)

这是probaby非常pymongo特定但它也是非常不必要的,因为聚合管道的标准形式的参数实际上是一个数组,也可以像这样简单地指定,例如:

request = [{ "$unwind": "$tags"}, { "$group": { "_id": "$tags" } }]

总是按顺序序列化,因此没有问题。

因此无需使用OrderedDict。

你可能会对最近对mongo shell(来自2.6)的更改感到困惑,因为它允许指定参数而不包装在数组中。但是JSON和其他一些语言一样希望它们的“字典/哈希”定义能够保持其指定的顺序。

因此,使用数组/列表语法仍然是首选实现。