Search code examples
mongodbmongodb-querypymongo

How to get matching subdocuments in mongodb


I have schema like this -

 {
   "_id":"ObjectId(""622f950e73043487031bb3ee"")",
   "outerTimeStamp" : "14-Mar-2022",
   "filtered":{
      "data":[
         {
            "Price":14350,
            "expiryDate":"17-Mar-2022",
            "info1":{
               "Price":14350,
               "expiryDate":"17-Mar-2022",
            },
            "info2":{
               "Price":14350,
               "expiryDate":"17-Mar-2022"
            }
         },
         {
            "Price":14350,
            "expiryDate":"17-Mar-2022",
            "info1":{
               "Price":14350,
               "expiryDate":"17-Mar-2022",
            },
            "info2":{
               "Price":14350,
               "expiryDate":"17-Mar-2022"
            }
         },
         ......
         ....
     ]
    }
}

I need all the subdocuments from a document where expiryDate == "17-Mar-2022"

I have used the following query -

db.collection.find({ "filtered.data" : { $elemMatch : { "expiryDate" : "17-Mar-2022"}} }, { "filtered.data.$" : 1 })

it just returns the first matching sub-document but there are many other documents also available

if I don't use ".$" then it returns all those documents even those that don't match with the query conditions.

thanks in advance


Solution

  • You can do simpy by aggregation/$filter:

    db.collection.aggregate([
    {
      $match: {
      "filtered.data.expiryDate": "17-Mar-2022"
      }
    },
    {
     $addFields: {
      "filtered.data": {
        "$filter": {
          "input": "$filtered.data",
          "as": "d",
          "cond": {
            "$eq": [
              "$$d.expiryDate",
              "17-Mar-2022"
            ]
           }
         }
        }
      }
     }
    ])
    

    For best results index need to be created on "filtered.data.expiryDate"

    playground