Est-ce qu'il y a une chose d'elseif en MongoDB à $cond tout en agrégeant

J'ai donc besoin d'un champ personnalisé calculé en MongoDB comme suit

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

j'utilise l'agrégation avec l'énoncé de projet$. Mais l'opérateur $cond n'autorise pas elseif (sous-grouper le else) et ne permet que deux branches statiques si et sinon. Utiliser un elseif emboîté provoque

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

Voici ma requête(ce qui me donne le message d'erreur)

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

Est-il une méthode ou une solution de contournement. Mes excuses si c'est une question répétée mais je n'ai pas réussi à en trouver un similaire.

12
demandé sur humblerookie 2014-12-15 10:38:46

3 réponses

if..then..else mots-clés $cond opérateur ne sont un ajout récent comme des versions récentes de MongoDB, au moment de la rédaction. L'intention était de clarifier les choses mais, dans ce cas, cela semble avoir causé une certaine confusion.

if..then.else opérateur $cond est en effet un ternaire opérateur, tout comme serait implémenté dans de nombreux langages de programmation. Cela signifie Comme un " inline" conditionnel, plutôt que de créer des "blocs" de logique aux conditions, tout ce qui ne répond pas à la première condition appartient à else.

par conséquent, vous "emboîtez" les énoncés plutôt que de suivre les blocs:

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

Ternaire signifie trois conditions, ni plus ni moins. Donc, tous les if..then..else la logique doit être imbriquée.

25
répondu Neil Lunn 2016-11-07 16:02:03

MongoDB 3.4 a une nouvelle chose appelée $switch pour cette chose exacte!

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

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

6
répondu nort 2016-12-01 15:50:40

si vous utilisez uniquement object, alors

{
    $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 },
        ]
    }
}

et si vous utilisez Array find Data

{
    $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
répondu KARNAV PARGI 2018-09-27 07:37:36