Filtering array element depending on subdocument condition

Hello,

Here is the data structure I’m working with:

[{
  "roadVolume": {
    "stock": {
      "suppliers": [
        {
          "name": "supplier 1",
          "placeOfIncoterms": [
            {
              "name": "place A",
              "total": {}
            },
            {
              "name": "place B",
              "total": {}
            }
          ]
        },
        {
          "name": "supplier 2",
          "placeOfIncoterms": [
            {
              "name": "place C",
              "total": {
                "orderVolume": "value",
                "numberOfTrucks": "value"
              }
            },
            {
              "name": "place D",
              "total": {}
            }
          ]
        },
      ]
    }
  }
}]

I want to filter out the suppliers for which “total” field renders an empty object. In this example:

[{
  "roadVolume": {
    "stock": {
      "suppliers": [
        {
          "name": "supplier 2",
          "placeOfIncoterms": [
            {
              "name": "place C",
              "total": {
                "orderVolume": "value",
                "numberOfTrucks": "value"
              }
            }
          ]
        },
      ]
    }
  }
}]

I found a similar post (Mongodb aggregation remove null values from object with nested properties) but didn’t manage to adapt the solution to my use case. I did some tests with $filter and $reduce, but did not manage to reach a viable outcome. Also, I don’t want to $unwind and then $group back, to save on performance.

Your assistance is relly appreciated!

Hello @Antoine_Delequeuche,

You can use $map, $filter and $mergeObjects operators, something like this,

db.collection.aggregate([
  {
    $addFields: {
      "roadVolume.stock.suppliers": {
        $filter: {
          input: {
            $map: {
              input: "$roadVolume.stock.suppliers",
              in: {
                $mergeObjects: [
                  "$$this",
                  {
                    placeOfIncoterms: {
                      $filter: {
                        input: "$$this.placeOfIncoterms",
                        cond: { $ne: ["$$this.total", {}] }
                      }
                    }
                  }
                ]
              }
            }
          },
          cond: { $ne: ["$$this.placeOfIncoterms", []] }
        }
      }
    }
  }
])
2 Likes

Hello @turivishal,
Your solution works, thank you so much for helping out!

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.