最新のMongoDBリリースでは、次のことができます。それでも、配列を$concat
に「直接」適用することはできません。 ただし、$reduce
を使用できます 配列要素を操作してこれを生成するには:
db.collection.aggregate([
{ "$addFields": {
"values": {
"$reduce": {
"input": "$values",
"initialValue": "",
"in": {
"$cond": {
"if": { "$eq": [ { "$indexOfArray": [ "$values", "$$this" ] }, 0 ] },
"then": { "$concat": [ "$$value", "$$this" ] },
"else": { "$concat": [ "$$value", "_", "$$this" ] }
}
}
}
}
}}
])
もちろん、$indexOfArray
と組み合わせる しないために "_"
と「連結」します 配列の「最初の」インデックスである場合はアンダースコアを付けます。
また、私の追加の「願い」は$sum
で答えられました :
db.collection.aggregate([
{ "$addFields": {
"total": { "$sum": "$items.value" }
}}
])
この種の問題は、アイテムの配列を受け取る集計演算子を使用すると、一般的に少し高くなります。ここでの違いは、現在のドキュメントに存在する「配列要素」とは対照的に、コード化された表現で提供される「配列」の「配列」を意味することです。
ドキュメントに存在する配列内のアイテムのある種の連結を実際に行うことができる唯一の方法は、mapReduceのこの例のように、ある種のJavaScriptオプションを行うことです:
db.collection.mapReduce(
function() {
emit( this._id, { "values": this.values.join("_") } );
},
function() {},
{ "out": { "inline": 1 } }
)
もちろん、実際に何も集約していない場合、おそらく最善のアプローチは、クエリ結果の後処理でクライアントコード内でその「結合」操作を実行することです。ただし、ドキュメント全体で何らかの目的で使用する必要がある場合は、mapReduceが使用できる唯一の場所になります。
「たとえば」このようなものが機能することを望んでいることを追加できます:
{
"items": [
{ "product": "A", "value": 1 },
{ "product": "B", "value": 2 },
{ "product": "C", "value": 3 }
]
}
そして全体として:
db.collection.aggregate([
{ "$project": {
"total": { "$add": [
{ "$map": {
"input": "$items",
"as": "i",
"in": "$$i.value"
}}
]}
}}
])
ただし、 $add
であるため、このようには機能しません。 ドキュメントの配列ではなく、引数を期待します。はぁ! :(。これの「設計による」推論の一部は、変換の結果から渡される特異値の配列または「リスト」であるという理由だけで、それらが「保証」されていないという主張ができます。実際には、オペレーターが期待する「有効な」特異数値型の値です。少なくとも、現在実装されている「型チェック」の方法ではそうではありません。
つまり、今のところ、これを行う必要があります:
db.collection.aggregate([
{ "$unwind": "$items" },
{ "$group": {
"_id": "$_id",
"total": { "$sum": "$items.value" }
}}
])
また、残念ながら、このようなグループ化演算子を適用して文字列を連結する方法もありません。
したがって、これに対する何らかの変更を期待することも、 $map
のスコープ内で外部スコープの変数を変更できるようにする変更を期待することもできます。 何らかの方法で操作。より良い、さらに新しい$join
操作も大歓迎です。しかし、これらは執筆時点では存在せず、おそらくしばらくの間は存在しないでしょう。