sql >> Databasteknik >  >> NoSQL >> MongoDB

Finns det en annan sak i MongoDB till $cond under aggregering

Med moderna utgåvor (sedan MongoDB 3.4) skulle du använda $switch , som i princip är motsvarigheten till byte eller case nyckelord i andra språkimplementationer:

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

Detta undviker kapsling koden if..then..else villkor som kan göras med $cond och visas nedan. Men nedanstående visar fortfarande som ett exempel att detta alltid kan göras, även innan den nya operatören till och med den explicita if..then..else nyckelord eftersom den ursprungliga arraynotationen alltid bibehöll den syntaxen.

Notera också att en array av villkor här är vanligtvis också mycket lättare att konstruera programmatiskt än att skapa en kapslad datastruktur för uttalandet som behövdes med $cond .

if..then..else nyckelord till $cond operatören är bara ett nyligen tillägg från de senaste versionerna av MongoDB i skrivande stund ( MongoDB 2.6 var introduktionen av sökord . Den faktiska operatören var tillgänglig med release av aggregeringsramverket i MongoDB 2.2). Avsikten var för klarhet men i det här fallet verkar det ha orsakat viss förvirring.

Som en if..then.else operator $cond är verkligen en ternär operatör, precis som skulle implementeras i många programmeringsspråk. Detta betyder att som ett "inline" villkor, snarare än att skapa "block" av logik till villkoren, hör allt som inte uppfyller det första villkoret under else .

Därför "kapslar" du påståendena istället för att följa block:

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

Eller till och med med den ursprungliga arrayen notation, vilket vissa kanske föredrar om man bygger programsatsen:

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

Ternär betyder tre villkor, varken fler eller mindre. Så alla if..then..else logik måste vara kapslad.



  1. Varför ger PyMongo 3 ServerSelectionTimeoutError?

  2. Hur man använder SCAN med alternativet MATCH i Predis

  3. Mongoose - Sök efter text i tre fält baserat på poäng eller vikt

  4. Spring Mongodb Tidsstämpel Tidszon Missvisande