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

Sammenlign indlejret dokument med overordnet felt med mongoDB

Standardforespørgsler kan ikke "sammenligne" værdier i dokumenter. Dette er faktisk noget, du gør ved at bruge .aggregate() og $redact :

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

Her bruger vi $filter for at sammenligne værdierne for "amount" i det overordnede dokument til dem i arrayet. Hvis mindst én er "lig", så "$$KEEP" dokumentet, ellers "$$PRUNE"

I de seneste versioner kan vi forkorte det ved at bruge $indexOfArray .

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

Hvis du faktisk også kun ville have "matchende array-element(er)", så ville du tilføje en $filter i 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" ] }
      }
    }
  }}
])

Men hovedprincippet er naturligvis at "reducere" antallet af dokumenter, der returneres til kun dem, der faktisk matcher betingelsen som en "første" prioritet. Ellers laver du bare unødvendige beregninger og arbejde, der tager tid og ressourcer, for resultater, som du senere ville kassere.

Så "filtrer" først, og "omform" derefter som en prioritet.



  1. Oprettelse af en visningsfunktion uden at returnere et svar i Flask

  2. Hvordan opretter jeg en dynamisk lig-forespørgsel ved hjælp af Apache Camel og MongoDB?

  3. Hvornår skal man indeksere, hvad skal man indeksere i Mongoid?

  4. MongoDB $pull syntaks