node.jsmongodbmongodb-queryaggregation-framework

How to ignore a mongo pipeline stage conditionally based on field values?


addFields
{
  "items.product.title": "some title",
  "items.product.code": "some code"
}

This is an addFields stage in my query pipeline. Sometimes items field is an empty array before the execution of this stage and some other times it has items which also need product field to be added (in this stage). I want to make a condition for the execution or complete ignorance of this stage based on that. So, when items is an empty array I want to completely skip this stage and keep items untouched (leave it as an empty array), otherwise add new fields inside items.

Case 1 - items is empty:

// data before stage:
{
_id: "some id"
items: []
}
// expected output after stage (nothing is changed):
{
_id: "some id"
items: []
}

Case 2- items is not empty:

// data before stage:
{
_id: "some id"
items: [
 {
   item_id: "some id"
   count: 5  
 }
]
}
// expected output after stage:
{
_id: "some id"
items: [
 {
   item_id: "some id"
   count: 5  
   product  // product needs to be added
   {
      title: "some title" // these need to be added
      code: "some code"
   }
 }
]
}

How can I create a condition for the execution of a stage?


Solution

  • Query

    *in general you cant skip a $addFields stage but you can keep the old value based on condition, here if array is empty $map does nothing anyway, so we dont even need condition to keep the old value.

    Test code here

    db.collection.aggregate([
      {
        "$set": {
          "items": {
            "$map": {
              "input": "$items",
              "in": {
                "$mergeObjects": [
                  "$$i",
                  {
                    "product": {
                      "title": "some title",
                      "code": "some code"
                    }
                  }
                ]
              },
              "as": "i"
            }
          }
        }
      }
    ])