"Объект спецификации этапа трубопровода должен содержать ровно одно поле" при использовании OrderedDict
Я пытаюсь запустить команду aggregate:
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.
Мне кажется, что у меня есть каждый агрегатный этап в одном элементе упорядоченного dict.
Ответы
Ответ 1
Это probaby очень специфично для pymongo, но это также очень необязательно, поскольку стандартная форма аргументов для конвейера агрегации на самом деле является массивом и может также просто указываться так, например:
request = [{ "$unwind": "$tags"}, { "$group": { "_id": "$tags" } }]
который всегда будет упорядочиваться по порядку и как таковой не представляет проблемы.
Поэтому нет необходимости использовать OrderedDict.
Возможно, вы запутались в поведении с недавними изменениями в оболочке mongo (от версии 2.6), что позволяет указывать аргументы без переноса в массив. Но JSON, как и некоторые другие языки, ожидает, что их определения "словарь/хэш" будут поддерживать указанный порядок.
Таким образом, использование синтаксиса array/list является еще предпочтительной реализацией.