2017-09-28 3 views
5

1つのMongoDBアグリゲーションクエリによって複数のフィールドの異なる値を数えようとしています。mongodbアグリゲーションを使用した複数のフィールドの個別のカウント

だからここに私のデータです:

{ 
    "car_type": "suv", 
    "color": "red", 
    "num_doors": 4 
}, 
{ 
    "car_type": "hatchback", 
    "color": "blue", 
    "num_doors": 4 
}, 
{ 
    "car_type": "wagon", 
    "color": "red", 
    "num_doors": 4 
} 

私はそれぞれのフィールドの個別の回数たい:私はグループの複数のフィールドをすることができたし、その後の個別のカウントを行いますが、それだけで与えることができる

distinct_count_car_type=3 
distinct_count_color=2 
distinct_count_num_doors=1 

を私は最初のフィールドに数えます。それらのすべてではありません。 また、大きなデータセットです。

db.collection.aggregate([ 
    { 
     "$group": { 
      "_id": null, 
      "distinct_car_types": { "$addToSet": "$car_type" }, 
      "distinct_colors": { "$addToSet": "$color" }, 
      "distinct_num_doors": { "$addToSet": "$num_doors" } 
     } 
    }, 
    { 
     "$project": { 
      "distinct_count_car_type": { "$size": "$distinct_car_types" }, 
      "distinct_count_color": { "$size": "$distinct_colors" }, 
      "distinct_count_num_doors": { "$size": "$distinct_num_doors" } 
     } 
    } 
]) 

答えて

1

あなたがの... $objectToArray電源を探しています:以下の集計パイプラインを実行

+0

残念ながら私はmongodb 3.2と$ objectToArrayを使用していますが、マニュアルによれば3.4で導入されたと思います。 – Deckard

+0

正しい。 3.4.4へのアップグレードをお勧めします。 –

+0

だから私はあなたのソリューションをアップグレードして試しました。私が今持っている問題は、別のコレクションからの$ルックアップのために実際に配列に入っている動的なフィールドです。質問の先頭のコレクションは、$ルックアップのために私の結果の配列にあります。ですから、フィールド上で$ objectToArrayを実行しようとすると、「$ objectToArrayにはドキュメント入力が必要です:array」となります。そして、私は$ arrayToObjectをまず呼び出して、$ objectToArrayを呼び出すことができました。 "$ arrayToObjectには、 'key'と 'v'のオブジェクトキーが必要です。 – Deckard

4

はあなたに望ましい結果を与える必要があります!

db.foo.aggregate([ 
    {$project: {x: {$objectToArray: "$$CURRENT"}}} 
    ,{$unwind: "$x"} 
    ,{$match: {"x.k": {$ne: "_id"}}} 
    ,{$group: {_id: "$x.k", y: {$addToSet: "$x.v"}}} 
    ,{$addFields: {size: {"$size":"$y"}} } 
        ]); 

これが得られます:

{ "_id" : "num_doors", "y" : [ 4 ], "size" : 1 } 
{ "_id" : "color", "y" : [ "blue", "red" ], "size" : 2 } 
{ 
    "_id" : "car_type", 
    "y" : [ 
     "wagon", 
     "hatchback", 
     "suv" 
    ], 
    "size" : 3 
} 

をあなたが$projectまたは$addFieldsをすることができますが、ユニークな値のセットやサイズを含めたり除外し合うように。

+0

投影に「_id:0」を追加することもできます)。 –

+0

これは機能します。ありがとう!それは少し減速するが、それほど多くはない。私は新しい質問をする必要があるかもしれませんが、それらのオブジェクトが動的なフィールド数で構成されている場合はどうなりますか(つまり、フィールド名を事前にハードコードすることはできません)。マップ内の任意の数のフィールドに異なるカウントを得る方法はありますか?どうすればいい? – Deckard

+1

@Deckard下記を参照してください。 –

関連する問題