MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

Eingebettetes Dokument mit übergeordnetem Feld mit mongoDB vergleichen

Standardabfragen können keine Werte in Dokumenten "vergleichen". Dies ist eigentlich etwas, das Sie mit .aggregate() tun und $redact :

db.collection.aggregate([
  { "$redact": {
    "$cond": {
      "if": {
        "$gt": [
          { "$size": {
            "$filter": {
              "input": "$offers",
              "as": "o",
              "cond": { "$eq": [ "$$o.amount", "$amount" ] }
            }
          }},
          0
        ]
      },
      "then": "$$KEEP",
      "else": "$$PRUNE"
    }
  }}
])

Hier verwenden wir $filter um die Werte von "amount" zu vergleichen im übergeordneten Dokument zu denen innerhalb des Arrays. Wenn mindestens einer "gleich" ist, dann "$$KEEP" das Dokument, ansonsten "$$PRUNE"

In den neuesten Versionen können wir das mit $indexOfArray .

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

Wenn Sie eigentlich auch nur die "passenden Array-Elemente" wollen, dann würden Sie ein $filter in Projektion:

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

Aber das Hauptprinzip ist natürlich, die Anzahl der zurückgesendeten Dokumente auf nur zu "reduzieren". diejenigen, die tatsächlich der Bedingung entsprechen, als "erste" Priorität. Andernfalls führen Sie nur unnötige Berechnungen und Arbeiten durch, die Zeit und Ressourcen in Anspruch nehmen, für Ergebnisse, die Sie später verwerfen würden.

Also zuerst "filtern" und als zweites "umformen".