Avec MongoDB 4.2 et plus récent, la méthode de mise à jour peut désormais prendre un document ou un pipeline agrégé où les étapes suivantes peuvent être utilisées :
$addFields
et son alias$set
$project
et son alias$unset
$replaceRoot
et son alias$replaceWith
.
Armé de ce qui précède, votre opération de mise à jour avec le pipeline agrégé consistera à remplacer les tags
champ en concaténant un tags
filtré tableau et un tableau mappé de la liste d'entrée avec une recherche de données dans la carte :
Pour commencer, l'expression agrégée qui filtre le tableau de balises utilise le $filter
et il suit :
const myTags = ["architecture", "blabladontexist"];
{
"$filter": {
"input": "$tags",
"cond": {
"$not": [
{ "$in": ["$$this.t", myTags] }
]
}
}
}
qui produit le tableau filtré de documents
[
{ "t" : "contemporary", "n" : 2 },
{ "t" : "creative", "n" : 1 },
{ "t" : "concrete", "n" : 3 }
]
Maintenant, la deuxième partie consistera à dériver l'autre tableau qui sera concaténé au précédent. Ce tableau nécessite un $map
sur les myTags
tableau d'entrée comme
{
"$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 }
}
}
}
}
Le $map
ci-dessus
boucle essentiellement sur le tableau d'entrée et vérifie avec chaque élément s'il se trouve dans les tags
tableau comparant le t
propriété, si elle existe alors la valeur du n
champ du sous-document devient son n
actuel valeurexprimée avec
{
"$arrayElemAt": [
"$tags.n",
{ "$indexOfArray": [ "$tags.t", "$$this" ] }
]
}
sinon ajoutez le document par défaut avec une valeur n de 0.
Globalement, votre opération de mise à jour sera la suivante
Votre opération finale de mise à jour devient :
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 }
);