MongoDB query for given nested document

77 views Asked by At

Here i have shown only single document but array has such multiple documents, I want to get all the documents which have Internal storage ( Memory -> Internal ) of 128GB

Data :

[
    {
        "_id": "654686dc65bc1013eae01dad",
        "name": "Samsung Galaxy Tab A9+",
        "detailSpec": [
            {
                "category": "Network",
                "specifications": [
                    {
                        "name": "Technology",
                        "value": "GSM / HSPA / LTE / 5G",
                        "_id": "654686dc65bc1013eae01daf"
                    },
                    {
                        "name": "2G bands",
                        "value": "GSM 850 / 900 / 1800 / 1900 ",
                        "_id": "654686dc65bc1013eae01db0"
                    }
                ],
                "_id": "654686dc65bc1013eae01dae"
            },
            {
                "category": "Memory",
                "specifications": [
                    {
                        "name": "Card slot",
                        "value": "microSDXC (dedicated slot)",
                        "_id": "654686dc65bc1013eae01dc6"
                    },
                    {
                        "name": "Internal",
                        "value": "64GB 4GB RAM, 128GB 8GB RAM",
                        "_id": "654686dc65bc1013eae01dc7"
                    }
                ],
                "_id": "654686dc65bc1013eae01dc5"
            },
        ],
        "quickSpec": [
            {
                "name": "Display size",
                "value": "11.0\"",
                "_id": "654686dc65bc1013eae01de2"
            }
        ],
        "__v": 0
    }
]

I have tried this query but problem is, it is considering value field of all categories but i want to consider only "Memory" category and then check only for value fields which is inside the "Memory" category:

const filteredData = await Models.devices.find({
        $and: [
            {
                $and: [
                    {"detailSpec.category": "Memory"},
                    {"detailSpec.specifications.name": "Internal"},
                    {"detailSpec.specifications.value": new RegExp(informationAboutFilter.storage) }
                ]
            }
        ]
    })
console.log(new RegExp(informationAboutFilter.storage))
Output: /128/
1

There are 1 answers

0
jQueeny On BEST ANSWER

You can use $elemMatch to only match objects from your detailSpec array. You can then use the positional operator $ in your projection object because:

The positional $ operator limits the contents of an array to return the first element that matches the query condition on the array. Use $ in the projection document of the find() method or the findOne() method when you only need one particular array element in selected documents.

Change your query to:

const filteredData = await Models.devices.find({
  detailSpec: {
    $elemMatch: {
      category: "Memory",
      "specifications.name": "Internal",
      "specifications.value": {
        $regex: informationAboutFilter.storage
      }
    }
  }
},
{
  "detailSpec.$": 1
})

See HERE for a working example. You will notice the use of "$regex": "128" because the new RegExp function is not available on mongoplayground but they are equivelant.