MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

Compare o documento incorporado ao campo pai com o mongoDB


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.