D_Asti
D_Asti

Reputation: 69

Mongo aggregation: How to exclude items from array, if they don't have specific keys?

I have a following data:

{
  "Name": "Test"
  "Location": "Whatever",
  "customerServices": [
      {
        "id": "test",
        "cusId": "test",
        "adr": "Adr 1",
        "serviceCounty": "Center",
        "area": "village"
      },
      {
        "id": "test",
        "cusId": "test",
        "adr": "adr2",
        "serviceCounty": "West",
        "area": "city"
      },
      {
        "id": "test",
        "cusId": "test",
        "adr": "test",
        "serviceCounty": "West",
      }
  ]
}

I need to check the array of elements (customerServices field) and filter it then. I have to check that each element has the following 3 keys:

  1. adr
  2. serviceCounty
  3. area

If any of these keys is missing, then this item in the array should be totally excluded. So the final result in this example would be:

{
  "Name": "Test"
  "Location": "Whatever",
  "customerServices": [...],
  "filteredCustomerServices": [
      {
        "id": "test",
        "cusId": "test",
        "adr": "Adr 1",
        "serviceCounty": "Center",
        "area": "village"
      },
      {
        "id": "test",
        "cusId": "test",
        "adr": "adr2",
        "serviceCounty": "West",
        "area": "city"
      }
  ]
}

As you can see the last item was excluded, beacause it had 'area' key missing. Any ideas how to achieve that? Really stuck with this mongo aggregation topic.

Upvotes: 1

Views: 1007

Answers (1)

Dheemanth Bhat
Dheemanth Bhat

Reputation: 4452

Try this:

db.yourCollectionName.aggregate([
    {
        $unwind: "$customerServices"
    },
    {
        $addFields: {
            "customerServices.skip": {
                $and: [
                    { $ifNull: ["$customerServices.adr", false] },
                    { $ifNull: ["$customerServices.serviceCounty", false] },
                    { $ifNull: ["$customerServices.area", false] }
                ]
            }
        }
    },
    {
        $match: {
            "customerServices.skip": { $ne: false }
        }
    },
    {
        $group: {
            _id: "$_id",
            Name: { $first: "$Name" },
            Location: { $first: "$Location" },
            filteredCustomerServices: {
                $push: "$customerServices"
            }
        }
    }
])

Upvotes: 1

Related Questions