「2ステップ」の操作として、集約フレームワークを使用してこれを行うことができます。これは、最初に $pushを介してアイテムを配列に蓄積することです。
$ group
パイプラインを作成し、 $ concat
を使用します
$ reduce
最終的な投影で生成されたアレイについて:
db.collection.aggregate([
{ "$group": {
"_id": "$tag_id",
"client_id": { "$push": "$client_id" }
}},
{ "$addFields": {
"client_id": {
"$reduce": {
"input": "$client_id",
"initialValue": "",
"in": {
"$cond": {
"if": { "$eq": [ "$$value", "" ] },
"then": "$$this",
"else": {
"$concat": ["$$value", ",", "$$this"]
}
}
}
}
}
}}
])
$ cond
も適用します
ここでは、結果で空の文字列とコンマが連結されないようにするため、区切りリストのように見えます。
参考までに、JIRAの問題があります SERVER-29339
$ reduce
を要求します
アキュムレータ式
として実装されます $ group
で直接使用できるようにする
パイプラインステージ。すぐに発生する可能性は低いですが、理論的にはに置き換わるでしょう。 $ push
上記で、操作を単一のパイプラインステージにします。提案された構文のサンプルは、JIRAの問題に関するものです。
$ reduce
がない場合
(MongoDB 3.4が必要です)次に、カーソルを後処理します:
db.collection.aggregate([
{ "$group": {
"_id": "$tag_id",
"client_id": { "$push": "$client_id" }
}},
]).map( doc =>
Object.assign(
doc,
{ "client_id": doc.client_id.join(",") }
)
)
次に、 mapReduce
>
本当に必要な場合:
db.collection.mapReduce(
function() {
emit(this.tag_id,this.client_id);
},
function(key,values) {
return [].concat.apply([],values.map(v => v.split(","))).join(",");
},
{ "out": { "inline": 1 } }
)
もちろん、特定の mapReduce
に出力するのはどれですか _id
の形式 およびvalue
キーのセットとしてですが、基本的には出力です。
[]。concat.apply([]、values.map(...))
を使用します mapReduce
のため、「reducer」の出力は「区切り文字列」になる可能性があるためです。 大きな結果で段階的に機能するため、レデューサーの出力は別のパスで「入力」になる可能性があります。したがって、これが発生する可能性があることを期待し、それに応じて処理する必要があります。