sql >> Database >  >> NoSQL >> MongoDB

Is er iets anders in MongoDB om $ te conderen tijdens het aggregeren?

Met moderne releases (sinds MongoDB 3.4) zou je $switch , wat in feite de tegenhanger is van switch of case trefwoorden in andere taalimplementaties:

db.items.aggregate([
  { "$project": {
    "name": 1,
    "customfield": {
      "$switch": {
        "branches": [
          { "case": { "$eq": [ "$field1", "4" ] }, "then": 30 },
          { "case": { "$eq": [ "$field1", "8" ] }, "then": 25 }
        ],
        "default": 10
      }
    }
  }},
  { "$sort": { customfield: 1 }},
  { "$limit":12 }
])

Dit voorkomt nesting de if..then..else voorwaarden zoals kan worden gedaan met behulp van $cond en hieronder weergegeven. Maar het onderstaande laat nog steeds als voorbeeld zien dat dit altijd zou kunnen, zelfs vóór de nieuwe operator van zelfs de expliciete if..then..else trefwoorden omdat de oorspronkelijke matrixnotatie die syntaxis altijd handhaafde.

Merk ook op dat een array van voorwaarden hier is meestal ook een stuk eenvoudiger programmatisch te construeren dan het maken van een geneste gegevensstructuur voor de instructie zoals nodig was met $cond .

De if..then..else trefwoorden voor de $cond operator zijn slechts een recente toevoeging vanaf recente versies van MongoDB op het moment van schrijven ( MongoDB 2.6 was de introductie van de trefwoorden . De eigenlijke operator was beschikbaar met de release van het aggregatieraamwerk in MongoDB 2.2). De bedoeling was voor duidelijkheid, maar in dit geval lijkt het enige verwarring te hebben veroorzaakt.

Als een if..then.else operator $cond is inderdaad een ternair operator, net zoals zou worden geïmplementeerd in veel programmeertalen. Dit betekent dat als een "inline" voorwaarde, in plaats van "blokken" van logica aan de voorwaarden te maken, alles dat niet aan de eerste voorwaarde voldoet, onder else valt. .

Daarom "nest" je de uitspraken in plaats van blokken te volgen:

db.items.aggregate([
  { "$project": {
    "name": 1,
    "customfield": {
      "$cond": { 
        "if": { "$eq": [ "$field1", "4" ] }, 
        "then": 30,
        "else": {
          "$cond": {
            "if": { "$eq": ["$field1","8"]}, 
            "then": 25, 
            "else": 10
          }
        }
      }
    }
  }},
  { "$sort": { customfield: 1 }},
  { "$limit":12 }
]);

Of zelfs met de originele array notatie, die sommigen misschien verkiezen als ze de instructie programmatisch opbouwen:

db.items.aggregate([
  { "$project": {
    "name": 1,
    "customfield": {
      "$cond": [
         { "$eq": [ "$field1", "4" ] }, 
         30,
         { "$cond": [
           { "$eq": ["$field1","8"] },
           25, 
           10
         ]}
      ]
    }
  }},
  { "$sort": { customfield: 1 }},
  { "$limit":12 }
]);

Ternair betekent drie voorwaarden, niet meer en niet minder. Dus alle if..then..else logica moet genest zijn.



  1. Specifiek deel van document ophalen

  2. Hoe zaai je relaties voor Mongoid in Ruby on Rails?

  3. MongoDB $sinh

  4. Hoe $setDifference in array &Object te gebruiken met Mongo DB