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

C'è un'altra cosa in MongoDB su $ cond durante l'aggregazione

Con le versioni moderne (a partire da MongoDB 3.4) dovresti usare $switch , che è sostanzialmente la controparte di switch o case parole chiave in altre implementazioni linguistiche:

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

Ciò evita il nidificazione il if..then..else condizioni come è possibile fare utilizzando $cond e mostrato di seguito. Ma quanto segue mostra ancora come esempio che ciò può sempre essere fatto, anche prima del nuovo operatore anche dell'esplicito if..then..else parole chiave poiché la notazione dell'array originale ha sempre mantenuto quella sintassi.

Notando anche che un array di condizioni qui è in genere anche molto più facile da costruire in modo programmatico rispetto alla creazione di un nidificato struttura dei dati per l'istruzione come era necessario con $cond .

Il if..then..else parole chiave per $cond operator sono solo un'aggiunta recente rispetto alle versioni recenti di MongoDB al momento della scrittura ( MongoDB 2.6 è stata l'introduzione delle parole chiave . L'operatore effettivo era disponibile con il rilascio del framework di aggregazione in MongoDB 2.2). L'intenzione era di chiarezza, ma in questo caso sembra aver creato un po' di confusione.

Come if..then.else operatore $cond è infatti un ternario operatore, proprio come sarebbe implementato in molti linguaggi di programmazione. Ciò significa che come condizionale "inline", invece di creare "blocchi" di logica alle condizioni, tutto ciò che non soddisfa la prima condizione appartiene a else .

Pertanto "annidi" le istruzioni anziché seguire i blocchi:

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

O anche con l'array originale notazione, che alcuni potrebbero preferire se si costruisce l'istruzione in modo programmatico:

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

Ternario significa tre condizioni, né più né meno. Quindi tutto if..then..else la logica deve essere nidificata.