2016-03-25 6 views
2

私はMongoDBの集約パイプラインを使用して実現したいと思っています。私は1つのフィールドの配列をセット(すなわち、順序と重複を無視する)として扱い、それらをグループ化したいと考えています。例として、コレクションには、次のようになります。配列でドキュメントをグループ化し、配列をセットとして扱います

[ 
    { 
     _id: 1 
     names: ["a", "b"] 
    }, 
    { 
     _id: 2 
     names: ["c", "a"] 
    }, 
    { 
     _id: 3 
     names: ["b", "a"] 
    } 
] 

そして、私は戻って欲しい結果は次のようなものです:

[ 
    { 
     names: ["a", "b"], 
     count: 2 
    }, 
    { 
     names: ["a", "c"], 
     count: 1 
    } 
] 

は、ありがとう!

答えて

1

グループ化キーで一致させるには、結果を$sortにする必要があります。

db.collection.aggregate([ 
    { "$unwind": "$names" }, 
    { "$sort": { "_id": 1, "names": 1} }, 
    { "$group": { 
     "_id": "$_id", 
     "names": { "$push": "$names" } 
    }}, 
    { "$group": { 
     "_id": "$names", 
     "count": { "$sum": 1 } 
    }} 
]) 

戻りますが尋ねると同じように:

[ 
    { 
     "_id": ["a", "b"], 
     "count": 2 
    }, 
    { 
     "_id": ["a", "c"], 
     "count": 1 
    } 
] 

「セット」のように、アレイ上で動作するかなりの数の演算子がある一方で、それらのどれもが、「並べ替えません」本当に他の方法はありませんグループ化する際に適用される一貫した方法でコンテンツを配列します。これはあなたが$sortのときにのみ行われます。

db.testa.insert_many([ 
    { "a" : [ "a", "b" ] }, 
    { "a" : [ "b", "a" ] }, 
    { "a" : [ "b", "a", "a" ] } 
]) 

db.testa.aggregate({ "$project": { "_id": 0, "a": { "$setUnion": [ "$a", [] ] } } }) 

を当然のサンプルを返すこと:

{ "a" : [ "b", "a" ] } 
{ "a" : [ "a", "b" ] } 
{ "a" : [ "a", "b" ] } 

だから、あなたは「まだ希望のアレイは、「重複」が含まれている場合でも

、およびいくつかのセット変換を持っていたが、彼らはまだ一貫して注文されていません適用しましたグループ化のための一貫した「集合」を得るためには、$unwind$sortが必要です。

1

複数のアグリゲーションパイプラインをつなぎ合わせることで、確実に結果を得ることができます。

db.collection.aggregate([ 
{$unwind:"$names"}, 
{$sort:{_id:1, names:1}}, 
{$group:{_id:"$_id", names:{$push:"$names"}}}, 
{$group:{_id:"$names", count:{$sum:1}}}, 
{$project:{_id:0, names:"$_id", count:1}} 
]) 

それは発する:

{ 
    "count" : NumberInt(1), 
    "names" : [ 
     "a", 
     "c" 
    ] 
} 
{ 
    "count" : NumberInt(2), 
    "names" : [ 
     "a", 
     "b" 
    ] 
} 
関連する問題