sql >> Database >  >> NoSQL >> MongoDB

Vergelijk ingesloten document met bovenliggend veld met mongoDB

Standaardquery's kunnen geen waarden in documenten "vergelijken". Dit is eigenlijk iets wat je doet met .aggregate() en $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 gebruiken we $filter om de waarden van "amount" te vergelijken in het bovenliggende document naar die binnen de array. Als ten minste één "gelijk" is, dan "$$KEEP" het document, anders "$$PRUNE"

In de meest recente versies kunnen we dat inkorten met $indexOfArray .

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

Als je eigenlijk alleen de "overeenkomstige array-element(en)" ook wilt, dan zou je een $filter in projectie:

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

Maar het belangrijkste principe is natuurlijk om het aantal teruggestuurde documenten te "verminderen" tot alleen degenen die daadwerkelijk overeenkomen met de voorwaarde als een "eerste" prioriteit. Anders doe je gewoon onnodige berekeningen en werk dat tijd en middelen kost, voor resultaten die je later zou weggooien.

Dus "filter" eerst en "hervorm" als prioriteit.



  1. Passport.js en Mongoose.js vullen Gebruiker bij inloggen - verliest ingevuld veld op req.user

  2. Hoe deze MongoDB-query uit te voeren met Java?

  3. Mongodb en dat zoeken naar polygonen die een polygoon kruisen

  4. Redis gepijplijnde uitvoeringsvolgorde