Con MongoDB 4.2 e versioni successive, il metodo di aggiornamento ora può prendere un documento o una pipeline aggregata dove possono essere utilizzate le seguenti fasi:
$addFields
e il suo alias$set
$project
e il suo alias$unset
$replaceRoot
e il suo alias$replaceWith
.
In base a quanto sopra, la tua operazione di aggiornamento con la pipeline aggregata consisterà nell'overridere i tags
campo concatenando un tags
filtrato array e un array mappato dell'elenco di input con alcune ricerche di dati nella mappa:
Per cominciare, l'espressione aggregata che filtra l'array di tag utilizza $filter
e segue:
const myTags = ["architecture", "blabladontexist"];
{
"$filter": {
"input": "$tags",
"cond": {
"$not": [
{ "$in": ["$$this.t", myTags] }
]
}
}
}
che produce l'array filtrato di documenti
[
{ "t" : "contemporary", "n" : 2 },
{ "t" : "creative", "n" : 1 },
{ "t" : "concrete", "n" : 3 }
]
Ora la seconda parte sarà quella di derivare l'altro array che verrà concatenato a quanto sopra. Questo array richiede un $map
sopra myTags
inserire l'array come
{
"$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 }
}
}
}
}
Quanto sopra $map
essenzialmente scorre l'array di input e controlla con ogni elemento se è nei tags
array confrontando il t
proprietà, se esiste, allora il valore di n
il campo del documento secondario diventa il suo n
corrente valore espresso con
{
"$arrayElemAt": [
"$tags.n",
{ "$indexOfArray": [ "$tags.t", "$$this" ] }
]
}
altrimenti aggiungi il documento predefinito con un valore n pari a 0.
Nel complesso, l'operazione di aggiornamento sarà la seguente
L'operazione di aggiornamento finale diventa:
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 }
);