10

I got quite an annoying problem, and I can't seem to find any solution for my specific case. In my mongo agggregation pipeline, I'd like to add a field, and depending on the existence of another field's subfield, I'd like to assign the value of that other field's subfield, or 1 if that other field's subfield does not exist.

Here is what I tried:

pipelineStages.push(
{$addFields: 
    {field: 
        {$cond: [
             {$ne: ["$otherField.subField", null]}, 
                    "$otherField.subField", 1]
             }
        }
     }
 );

However, it only works fine for the case that the field exists. In the other, that new field is not added to the pipeline at all. Any ideas what I'm doing wrong?

Johann8
  • 649
  • 7
  • 20
Michał Szydłowski
  • 3,261
  • 5
  • 33
  • 55
  • Something like this `{$addFields: {field: { $ifNull: [ "$otherField.subField", 1 ] } } }` – s7vr Mar 23 '17 at 15:14
  • Possible duplicate of [MongoDB aggregate by field exists](http://stackoverflow.com/questions/25497150/mongodb-aggregate-by-field-exists) – s7vr Mar 23 '17 at 15:18
  • No. Like I said, I need the value of a subfield, not a field. The answer below doesn't cover that. – Michał Szydłowski Mar 23 '17 at 15:20
  • Imagine you have two docs with `{"otherField":{"subField":2, "extraField":3}}, {"otherField":{"oneField":3}}`. If you run the above query you should get output as `{"otherField" : { "subField" : 2, "extraField" : 3}, "field" : 2} {"otherField" : { "oneField" : 3 }, "field" : 1 } }`. Isn't that what you need ? If not please consider adding some sample document to the post. – s7vr Mar 23 '17 at 15:56

3 Answers3

12

Wrapping $ifNull in $cond does the trick, even with the subfield problem.

pipelineStages.push({
    $addFields: {
        newField: {
            $cond: [
                { 
                    "$ifNull": [ 
                        "$otherField.subField", 
                        false 
                    ] 
                },
                "$otherField.subField",
                1
            ]
        }
     }
 );
Johann8
  • 649
  • 7
  • 20
4

To check if the field exists and is not null, use:

pipelineStages.push({ 
  $addFields: {
    field: {
      $cond: [
        {"$gt": [$otherField, null]}, "$otherField.subField", 1
      ]
    }
  }
})

On the contrary, to check if the field doesn't exist or is null, use:

{"$lte": [$otherField, null]}
Ricky Boyce
  • 1,772
  • 21
  • 26
2

Did you try this version of condition:

pipelineStages.push({ $addFields: 
    {field: 
        {$cond: [{$and: [{"$otherField": {"$exists": true}}, {"$otherField.subField": {"$exists": true}}]}, "$otherField.subField", 1]
        }
    }
 });
Vitalii Andrusishyn
  • 3,984
  • 1
  • 25
  • 31