2014-12-15 17 views
11

Quindi ho bisogno di un campo personalizzato calcolato in MongoDB come segue

if(field1 =="A") ->customfield=10 
else if(field1 =="B" )->customfield=20 
else (field1 =="C") ->customfield=15 

sto usando aggregazione insieme con l'istruzione $ progetto. Ma l'operatore $ cond non consente elseif (sottraendo il resto) e consente semplicemente due rami statici in caso contrario. Utilizzando un elseif nidificato provoca

"exception: field inclusion is not allowed inside of $expressions"

Heres la mia domanda (che mi dà l'errore)

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

Esiste un metodo o soluzione a questo. Le mie scuse se questa è una domanda ripetuta, ma non sono riuscito a trovarne una simile.

+0

hai "$ field1" e poi "campo1". Errore di battitura? –

+0

Grazie, ma questo è stato il risultato della mia fretta (nel battere a macchina). Modificato lo stesso per riflettere la query originale, scuse per la confusione. – humblerookie

+0

Non sono sicuro al 100%, ma non penso ci sia alcuna sintassi che possa accorciare la tua query. Dovrai nidificare il 'if' all'interno di' else'. – ujvl

risposta

22

I if..then..else parole chiave per l'operatore $cond sono solo una recente aggiunta al versioni recenti di MongoDB al momento della scrittura. L'intenzione era di chiarezza, ma in questo caso sembra aver causato qualche confusione.

Come operatore if..then.else$cond è in effetti un operatore ternary, proprio come sarebbe implementato in molti linguaggi di programmazione. Ciò significa come condizionale "in linea", piuttosto che creare "blocchi" di logica per le condizioni, tutto ciò che non soddisfa la prima condizione appartiene a else.

pertanto è "nido" il bilancio, piuttosto che 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 } 
]); 

ternario significa tre condizioni, né più né meno. Quindi la logica if..then..else deve essere annidata.

+0

Oh, mi piacerebbe, U aveva digitato un po 'prima di correggerlo da solo. Nonethelss segnerà questo come risposta, Grazie – humblerookie

+0

@ neil-lunn: Hai perso la doppia citazione dopo la parola chiave in un'altra parte –

+0

che la query è corretta. Voglio solo codificare questa query sopra in C++ usando mongo :: BSONArrayBuilder aBuilder; Qualcuno può aiutarmi? come sotto mongo :: BSONArrayBuilder aBuilder; aBuilder.append (BSON (*** bisogno di costruire la query qui con $ cond **); mongo :: BSONArray aAggregationQuery = aBuilder.arr(); _Collection.aggregate (aAggregationQuery) ... – PAL