Com o MongoDB 4.2 e mais recente, o método de atualização agora pode pegar um documento ou um pipeline agregado onde as seguintes etapas podem ser usadas:
$addFields
e seu alias$set
$project
e seu alias$unset
$replaceRoot
e seu alias$replaceWith
.
Armado com o acima, sua operação de atualização com o pipeline agregado será substituir as
tags
campo concatenando uma tags
filtrada array e um array mapeado da lista de entrada com alguma pesquisa de dados no mapa:Para começar, a expressão agregada que filtra a matriz de tags usa o
$filter
e segue:const myTags = ["architecture", "blabladontexist"];
{
"$filter": {
"input": "$tags",
"cond": {
"$not": [
{ "$in": ["$$this.t", myTags] }
]
}
}
}
que produz a matriz filtrada de documentos
[
{ "t" : "contemporary", "n" : 2 },
{ "t" : "creative", "n" : 1 },
{ "t" : "concrete", "n" : 3 }
]
Agora a segunda parte será derivar o outro array que será concatenado ao anterior. Esta matriz requer um
$map
sobre as myTags
matriz de entrada como {
"$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 }
}
}
}
}
O
$map
acima
essencialmente faz um loop sobre a matriz de entrada e verifica com cada elemento se está nas tags
array comparando o t
propriedade, se existir, então o valor do n
campo do subdocumento se torna seu n
atual valor expresso com {
"$arrayElemAt": [
"$tags.n",
{ "$indexOfArray": [ "$tags.t", "$$this" ] }
]
}
caso contrário, adicione o documento padrão com um valor n de 0.
No geral, sua operação de atualização será a seguinte
Sua operação de atualização final se torna:
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 }
);