As consultas padrão não podem "comparar" valores em documentos. Na verdade, isso é algo que você faz usando
.aggregate()
e $redact
:db.collection.aggregate([
{ "$redact": {
"$cond": {
"if": {
"$gt": [
{ "$size": {
"$filter": {
"input": "$offers",
"as": "o",
"cond": { "$eq": [ "$$o.amount", "$amount" ] }
}
}},
0
]
},
"then": "$$KEEP",
"else": "$$PRUNE"
}
}}
])
Aqui usamos
$filter
para comparar os valores de "amount"
no documento pai para aqueles dentro da matriz. Se pelo menos um for "igual", então "$$KEEP"
o documento, caso contrário, "$$PRUNE"
Nas versões mais recentes, podemos encurtar isso usando
$indexOfArray
. db.collection.aggregate([
{ "$redact": {
"$cond": {
"if": {
"$ne": [
{ "$indexOfArray": [ "$offers.amount", "$amount" ] },
-1
]
},
"then": "$$KEEP",
"else": "$$PRUNE"
}
}}
])
Se você realmente quisesse apenas os "elementos de matriz correspondentes" também, adicionaria um
$filter
em projeção:db.collection.aggregate([
{ "$redact": {
"$cond": {
"if": {
"$gt": [
{ "$size": {
"$filter": {
"input": "$offers",
"as": "o",
"cond": { "$eq": [ "$$o.amount", "$amount" ] }
}
}},
0
]
},
"then": "$$KEEP",
"else": "$$PRUNE"
}
}},
{ "$project": {
"amount": 1,
"offers": {
"$filter": {
"input": "$offers",
"as": "o",
"cond": { "$eq": [ "$$o.amount", "$amount" ] }
}
}
}}
])
Mas o princípio principal é, obviamente, "reduzir" o número de documentos devolvidos a somente aqueles que realmente correspondem à condição como uma "primeira" prioridade. Caso contrário, você está apenas fazendo cálculos desnecessários e trabalho que consome tempo e recursos, para resultados que mais tarde você descartaria.
Portanto, "filtre" primeiro e "reformule" em segundo lugar como prioridade.