MongoDB 4.2以降では、更新メソッドがドキュメントまたは集約パイプライン 次のステージを使用できます:
-
$ addFields
およびそのエイリアス$ set
-
$ project
およびそのエイリアス$ unset
-
$ replaceRoot
およびそのエイリアス$ replaceWith
。
上記を武器に、集約パイプラインを使用した更新操作は、タグ
をオーバーライドすることです。 フィルタリングされたタグ
を連結してフィールド 配列と、マップ内のデータルックアップを含む入力リストのマップされた配列:
まず、タグ配列をフィルタリングする集計式は、 $ filter
そしてそれは続く:
const myTags = ["architecture", "blabladontexist"];
{
"$filter": {
"input": "$tags",
"cond": {
"$not": [
{ "$in": ["$$this.t", myTags] }
]
}
}
}
フィルタリングされたドキュメントの配列を生成します
[
{ "t" : "contemporary", "n" : 2 },
{ "t" : "creative", "n" : 1 },
{ "t" : "concrete", "n" : 3 }
]
次に、2番目の部分は、上記に連結される他の配列を導出することです。この配列には、 $ map
が必要です。
myTags
上 入力配列として
{
"$map": {
"input": myTags,
"in": {
"$cond": {
"if": { "$in": ["$$this", "$tags.t"] },
"then": {
"t": "$$this",
"n": {
"$sum": [
{
"$arrayElemAt": [
"$tags.n",
{ "$indexOfArray": [ "$tags.t", "$$this" ] }
]
},
1
]
}
},
"else": { "t": "$$this", "n": 0 }
}
}
}
}
上記の $ map
基本的に入力配列をループし、各要素がタグ
にあるかどうかを確認します t
を比較する配列 プロパティ、存在する場合は、 n
の値 サブドキュメントのフィールドが現在のn
になります で表される値
{
"$arrayElemAt": [
"$tags.n",
{ "$indexOfArray": [ "$tags.t", "$$this" ] }
]
}
それ以外の場合は、n値が0のデフォルトドキュメントを追加します。
全体として、更新操作は次のようになります
最終的な更新操作は次のようになります:
const myTags = ["architecture", "blabladontexist"];
db.getCollection('coll').update(
{ "_id": "1234" },
[
{ "$set": {
"tags": {
"$concatArrays": [
{ "$filter": {
"input": "$tags",
"cond": { "$not": [ { "$in": ["$$this.t", myTags] } ] }
} },
{ "$map": {
"input": myTags,
"in": {
"$cond": [
{ "$in": ["$$this", "$tags.t"] },
{ "t": "$$this", "n": {
"$sum": [
{ "$arrayElemAt": [
"$tags.n",
{ "$indexOfArray": [ "$tags.t", "$$this" ] }
] },
1
]
} },
{ "t": "$$this", "n": 0 }
]
}
} }
]
}
} }
],
{ "upsert": true }
);