it-swarm.com.de

Gibt es noch eine andere Sache, wenn in MongoDB $ beim Aggregieren anfällt

Ich brauche also ein benutzerdefiniertes Feld, das in MongoDB wie folgt berechnet wird

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

Ich verwende die Aggregation zusammen mit der $ project-Anweisung. Der $ cond-Operator lässt jedoch elseif nicht zu (untergliedert das else) und erlaubt lediglich zwei statische Zweige if und else. Die Verwendung verschachtelter elseif-Ursachen 

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

Heres meine Abfrage (die mir den Fehler gibt)

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

Gibt es eine Methode oder Problemumgehung? Ich entschuldige mich, wenn dies eine wiederholte Frage ist, aber ich konnte keine ähnliche Frage finden.

14
humblerookie

Die if..then..else-Schlüsselwörter für den Operator $cond sind nur eine kürzlich hinzugefügte Erweiterung von MongoDB zum Zeitpunkt des Schreibens. Die Absicht war der Klarheit, aber in diesem Fall scheint es einige Verwirrung zu geben.

Als if..then.else-Operator $cond ist er tatsächlich ein ternary - Operator, genauso wie es in vielen Programmiersprachen implementiert wäre. Dies bedeutet als "Inline" -Bedingung, anstatt "Logikblöcke" für die Bedingungen zu erstellen. Alles, was die erste Bedingung nicht erfüllt, gehört zu else.

Deshalb "verschachteln" Sie die Anweisungen, anstatt den Blöcken zu folgen:

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

Ternär bedeutet drei Bedingungen, nicht mehr und nicht weniger. Daher muss die gesamte if..then..else-Logik verschachtelt sein.

27
Neil Lunn

MongoDB 3.4 hat eine neue Sache namens $switch für genau diese Sache!

$switch: {
   branches: [
      { case: <expression>, then: <expression> },
      { case: <expression>, then: <expression> },
      ...
   ],
   default: <expression>
}

https://docs.mongodb.com/manual/reference/operator/aggregation/switch/

8
nort

wenn Sie nur Objekt verwenden, dann

{
    $cond: {
        $and: [
            { if: { $eq: ["$$field1", 'A'] }, then: '10', else: 15 },
            { if: { $eq: ["$$field1", 'B'] }, then: '20', else: 15 },
            { if: { $eq: ["$$field1", 'C'] }, then: '10', else: 15 },
        ]
    }
}

Und wenn Sie Array verwenden, finden Sie Daten 

{
    $map: {
        input: "$fields", as: "field1", in: {
            $cond: {
                $and: [
                    { if: { $eq: ["$$field1", 'A'] }, then: '10', else: 15 },
                    { if: { $eq: ["$$field1", 'B'] }, then: '20', else: 15 },
                    { if: { $eq: ["$$field1", 'C'] }, then: '10', else: 15 },
                ]
            }
        }
    }
}
0
KARNAV PARGI