0

I have a collection like below

{
    relatedProperties: [ //Array
       {
            locations: [ //Array 
                {
                    value: "Brazil"
                },
                {
                    value: "Germany"
                }
            ]
       },
       {
            locations: []
       },
       {
            locations: null
       }
    ]
}

How do I write an aggregation to make only the empty or null arrays to have a default value like;

locations: [  
                {
                    value: "India"
                }
           ]

2 Answers 2

2

You can use $mergeObjects to keep other fields whatever they are:

db.collection.aggregate([
  {
    $project: {
      relatedProperties: {
        $map: {
          input: "$relatedProperties",
          as: "rp",
          in: {
            $cond: {
              if: {
                $eq: [
                  {
                    $ifNull: [
                      "$$rp.locations",
                      []
                    ]
                  },
                  []
                ]
              },
              then: {
                $mergeObjects: [
                  "$$rp",
                  {
                    locations: [
                      {
                        value: "India"
                      }
                    ]
                  }
                ]
              },
              else: "$$rp"
            }
          }
        }
      }
    }
  }
])
Sign up to request clarification or add additional context in comments.

Comments

1

The processing can also be done using $map operator. The following query can get us the expected output:

db.collection.aggregate([
  {
    $addFields:{
      "relatedProperties":{
        $map:{
          "input":"$relatedProperties",
          "as":"relatedProperty",
          "in":{
            "name":"$$relatedProperty.name",
            "age":"$$relatedProperty.age",
            "org":"$$relatedProperty.org",
            "locations":{
              $cond:[
                {
                  $in:["$$relatedProperty.locations",[null,[]]]
                },
                [
                  {
                    "value":"India"
                  }
                ],
                "$$relatedProperty.locations"
              ]
            }
          }
        }
      }
    }
  }
]).pretty()

Data set:

{
    "_id" : ObjectId("5d666236986fb04b2aeabe2a"),
    "relatedProperties" : [
        {
            "locations" : [
                {
                    "value" : "Brazil"
                },
                {
                    "value" : "Germany"
                }
            ],
            "name" : "ABC",
            "age" : "12",
            "org" : {
                "value" : "org1"
            }
        },
        {
            "locations" : [ ],
            "name" : "CDE",
            "age" : "30",
            "org" : {
                "value" : "org2"
            }
        },
        {
            "locations" : null,
            "name" : "EFG",
            "age" : "20",
            "org" : {
                "value" : "org3"
            }
        }
    ]
}

Output:

{
    "_id" : ObjectId("5d666236986fb04b2aeabe2a"),
    "relatedProperties" : [
        {
            "name" : "ABC",
            "age" : "12",
            "org" : {
                "value" : "org1"
            },
            "locations" : [
                {
                    "value" : "Brazil"
                },
                {
                    "value" : "Germany"
                }
            ]
        },
        {
            "name" : "CDE",
            "age" : "30",
            "org" : {
                "value" : "org2"
            },
            "locations" : [
                {
                    "value" : "India"
                }
            ]
        },
        {
            "name" : "EFG",
            "age" : "20",
            "org" : {
                "value" : "org3"
            },
            "locations" : [
                {
                    "value" : "India"
                }
            ]
        }
    ]
}

7 Comments

Hey Sharma, thanks for the help... but I do not want to perform an 'unwind' operation for a reason. Looking for the "$addFields" operation which can just replace all empty / null arrays with default.
@Shibu Please try the second approach mentioned in the answer.
@Sharma, second approach worked fine... but other fields adjacent to locations are omitted in the result.
Can you please post complete sample document?
{ "relatedProperties": [{ "locations": [{ "value": "Brazil" }, { "value": "Germany" }], "name": "ABC", "age": "12", "org": { "value": "org1" } }, { "locations": [], "name": "CDE", "age": "30", "org": { "value": "org2" } }, { "locations": null, "name": "EFG", "age": "20", "org": { "value": "org3" } }] }
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.