0

I am trying to filter the products from the product collection based on price.

Current Product Collection:

[
{
  _id: ObjectId("56f277b1279871c20b8b4566"),
  product_name:'sample product 1',
  product_items:[
         {
            product_price: 50.99,
            product_item_no: '123456789',
            product_images:['default.png']
          },
          {
            product_price: 11.99,
            product_item_no: '683456789',
            product_images:['default2.png']
          }
       ],
       product_status_is_active: true,

},
{
  _id: ObjectId("56f277b1279871c20b8b4567"),
  product_name:'sample product 2',
  product_items:[
         {
            product_price: 12.99,
            product_item_no: '45678923',
            product_images:['default2.png']
          },
          {
            product_price: 66.99,
            product_item_no: '683456789',
            product_images:['default4.png']
          }
       ],
       product_status_is_active: true,
}
]

mongoose query:

{
     '$match': {
       product_status_is_active: true,
       product_items: { '$elemMatch': { product_price: { '$gte': 60, '$lte': 100 } } }
    }
  },

Current Output:

{
  _id: ObjectId("56f277b1279871c20b8b4567"),
  product_name:'sample product 2',
  product_items:[
         { // This object should not display
            product_price: 12.99,
            product_item_no: '45678923',
            product_images:['default2.png']
          },
          {
            product_price: 66.99,
            product_item_no: '683456789',
            product_images:['default4.png']
          }
       ],
       product_status_is_active: true,
}

Expecting output like:

{
  _id: ObjectId("56f277b1279871c20b8b4567"),
  product_name:'sample product 2',
  product_items:[
          {
            product_price: 66.99,
            product_item_no: '683456789',
            product_images:['default4.png']
          }
       ],
       product_status_is_active: true,
}

But the Output of my Query contains also the nonmatching product_price.

How I can force MongoDB to return only the product_price, which matched my query?

Greetings and thanks.

  • 1
    Does this answer your question? [Retrieve only the queried element in an object array in MongoDB collection](https://stackoverflow.com/questions/3985214/retrieve-only-the-queried-element-in-an-object-array-in-mongodb-collection) – Alex Blex Sep 23 '20 at 08:46

1 Answers1

1

You can achieve this with aggregation.

  1. Match the product_status_is_active:true
  2. Use $filter to filter the array based on condion
  3. Match aging to empty product_items array

The aggregation stages are

[
  {
    $match: {
      "product_status_is_active": true
    }
  },
  {
    $addFields: {
      product_items: {
        $filter: {
          input: "$product_items",
          cond: {
            $and: [
              {
                $gte: [
                  "$$this.product_price",
                  60
                ]
              },
              {
                $lte: [
                  "$$this.product_price",
                  100
                ]
              }
            ]
          }
        }
      }
    }
  },
  {
    $match: {
      product_items: {
        $ne: []
      }
    }
  }
]

Working Mongo playground

varman
  • 7,839
  • 1
  • 15
  • 43