web-dev-qa-db-ja.com

OrderedDictを使用する場合、「パイプラインステージ仕様オブジェクトにはフィールドを1つだけ含める必要があります」

集約コマンドを実行してみます。

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つのアイテムに各集計ステージがあるように見えます。

15
bortzmeyer

これは非常にpymongo固有のprobabyですが、集約パイプラインの引数の標準形式は実際には配列であり、次のように単純に指定することもできるため、これも非常に不要です。

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

これは常に順番にシリアル化されるため、問題はありません。

したがって、OrderedDictを使用する必要はありません。

おそらく、配列でラップせずに引数を指定できるようにする(2.6からの)mongo Shellへの最近の変更と、動作を混同しているでしょう。しかし、JSONは他のいくつかの言語と同様に、「辞書/ハッシュ」定義が指定された順序を維持することを期待しています。

したがって、配列/リスト構文の使用はstillが推奨される実装です。

12
Neil Lunn