Mit MongoDB 4.2 und höher kann die Aktualisierungsmethode jetzt ein Dokument oder eine aggregierte Pipeline wobei die folgenden Stufen verwendet werden können:
$addFields
und sein Alias $set
$project
und sein Alias $unset
$replaceRoot
und sein Alias $replaceWith
.
Ausgestattet mit dem Obigen besteht Ihr Aktualisierungsvorgang mit der Aggregatpipeline darin, die Tags
zu überschreiben durch Verketten eines gefilterten tags
Array und ein gemapptes Array der Eingabeliste mit einigen Datensuchen in der Map:
Zunächst einmal verwendet der Aggregatausdruck, der das Tags-Array filtert, den Code <>$filter und es folgt:
const myTags = ["architecture", "blabladontexist"];
{
"$filter": {
"input": "$tags",
"cond": {
"$not": [
{ "$in": ["$$this.t", myTags] }
]
}
}
}
die das gefilterte Array von Dokumenten erzeugt
[
{ "t" : "contemporary", "n" : 2 },
{ "t" : "creative", "n" : 1 },
{ "t" : "concrete", "n" : 3 }
]
Nun besteht der zweite Teil darin, das andere Array abzuleiten, das mit dem obigen verkettet wird. Dieses Array erfordert einen $map
über die myTags
Eingabearray als
{
"$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 }
}
}
}
}
Der obige $map
durchläuft im Wesentlichen das Eingabearray und prüft bei jedem Element, ob es in den tags
enthalten ist Array, das t
vergleicht Eigenschaft, falls vorhanden, dann der Wert von n
Feld des Unterdokuments wird zu seinem aktuellen n
Wert ausgedrückt mit
{
"$arrayElemAt": [
"$tags.n",
{ "$indexOfArray": [ "$tags.t", "$$this" ] }
]
}
andernfalls fügen Sie das Standarddokument mit einem n-Wert von 0 hinzu.
Insgesamt sieht Ihr Aktualisierungsvorgang wie folgt aus
Ihr letzter Aktualisierungsvorgang wird zu:
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 }
);