MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

Confronta il documento incorporato con il campo padre con mongoDB

Le query standard non possono "confrontare" i valori nei documenti. Questo è in realtà qualcosa che fai 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"
    }
  }}
])

Qui utilizziamo $filter per confrontare i valori di "amount" nel documento padre a quelli all'interno dell'array. Se almeno uno è "uguale", allora "$$KEEP" il documento, altrimenti "$$PRUNE"

Nelle versioni più recenti, possiamo abbreviarlo usando $indexOfArray .

db.collection.aggregate([
  { "$redact": {
    "$cond": {
      "if": {
        "$ne": [
          { "$indexOfArray": [ "$offers.amount", "$amount" ] },
          -1
        ]
      },
      "then": "$$KEEP",
      "else": "$$PRUNE"
    }
  }}
])

Se in realtà volevi anche solo gli "elementi corrispondenti dell'array", dovresti aggiungere un $filter in proiezione:

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" ] }
      }
    }
  }}
])

Ma il principio fondamentale è ovviamente quello di "ridurre" il numero di documenti restituiti a solo quelli che effettivamente soddisfano la condizione come priorità "prima". Altrimenti stai solo facendo calcoli inutili e lavori che richiedono tempo e risorse, per risultati che in seguito vorresti scartare.

Quindi prima "filtra" e poi "rimodella" come priorità.