Search code examples
mongodbmongodb-queryaggregation-framework

How to filter the array of object using array of inputs in mongodb aggregation way


am new to mongodb. Below is my aggregation output. Now I need to filter one more level of my output based on fields productName and customer_details.region

Output:

[{
  "_id":  1,
  "productName": "Product10",  
  "customer_details": [
    {       
      "codeName": "MUI",
      "customerName": "MUI",
      "region": "USA"
    }
  ]
},
{
  "_id":  2,
  "productName": "Product11",  
  "customer_details": [
    {       
      "codeName": "MUI",
      "customerName": "MUI",
      "region": "Africa"
    }
  ]
},
{
  "_id":  3,
  "productName": "Product12",  
  "customer_details": [
    {       
      "codeName": "MUI",
      "customerName": "MUI",
      "region": "Germany"
    }
  ]
}]

Expected output:

I need to query productName but with multiple name like below ['Product10', 'product11']

mongodb aggregation stage should return only the objects which has productName Product10 , Product11.

Similarly the customer_details, from frontEnd they will pass ['Africa', 'USA'] and expected the result of object only having those region's.

I used $match but its not accepting array. sample code i tried below one last stage of my aggregation pipeline

{
$match: {
productName: "MUI"
}
}

Please guide me, how to achieve it.


Solution

  • Not sure if I've understood. Maybe you want only objects that match containing "productName" and "region" or only objects that match "productName" and for those then filter and return only desired "region"?

    The second one is only to add $match and $project with $filter to the pipeline:

    The goal here is:

    • First $match with $in to get only elements where productName is into the array.
    • Then $project to output desired values. In this case desired value is the customer_details filtered. And following the same idea, use $in to get only elements into the array where region is into the array.
    {
      "$match": {
        "productName": {
          "$in": ["Product10", "Product11"]
        }
      }
    },
    {
      "$project": {
        "productName": 1,
        "customer_details": {
          "$filter": {
            "input": "$customer_details",
            "cond": {
              "$in": ["$$this.region", [ "Africa", "USA"]]
            }
          }
        }
      }
    }
    

    Example here.

    Also if you want to get objects where exists both conditions yo can add an extra $match stage if there are no regions:

    In this example the concept is that, if any region match with the array, the filtered element will be empty. So in the next stage only $match where the array is not empty and you will get only elements where contains productName and region.

    {
      "$match": {
        "customer_details": { "$ne": [] }
      }
    }
    

    Example here