skip to Main Content

I trying to match the data in Subarray for some reason it is grouped like this.

Data :

{
"_id": 1,
"addresDetails": [
    [
        {
            "Name":"John",
            "Place":"Berlin",
            "Pincode":"10001"
        },
        {
            "Name":"Sarah",
            "Place":"Newyork",
            "Pincode":"10002"
        }
    ],
    [
        {
            "Name":"Mark",
            "Place":"Tokyo",
            "Pincode":"10003"
        },
        {
            "Name":"Michael",
            "Place":"Newyork",
            "Pincode":"10002"
        }
    ]
]
}

I tried with this Match query:

{
  "$match":{
    "attributes":{
       "$elemMatch":{
            "$in":["Mark"]
            }
        }
    }
}

I am getting No data found , How do i match the elements in this subarrays.

2

Answers


  1. Query

    • aggregation way, in general if you are stuck and query operators or update operators seems not enough, aggregation provides so much more operators, and its alternative.
    • 2 nested filter in the 2 level arrays to find a Name in array [Mark]

    *maybe there is a shorter more declarative way with $elemMatch, and possible a way to use index, also think about schema change, maybe you dont really need array with array members (the bellow doesnt use index)

    *i used addressDetails remove the one s else you will get empty results

    Playmongo

    aggregate(
    [{"$match": 
       {"$expr": 
         {"$ne": 
           [{"$filter": 
               {"input": "$addressDetails",
                "as": "a",
                "cond": 
                 {"$ne": 
                   [{"$filter": 
                       {"input": "$$a",
                        "as": "d",
                        "cond": {"$in": ["$$d.Name", ["Mark"]]}}},
                    []]}}},
            []]}}}])
    
    Login or Signup to reply.
  2. You can apparently nest elemMatch as well, e.g.:

    db.collection.find({
      "addresDetails": {
        $elemMatch: {
          $elemMatch: {
            "Name": "Mark"
          }
        }
      }
    })
    

    This matches your document, as shown by this mongo playground link, but is probably not very efficient.

    Alternatively you can use aggregations. For example unwind may help to flatten out your nested arrays, and allow for easier match afterwards.

    db.collection.aggregate([
      {
        "$unwind": "$addresDetails"
      },
      {
        "$match": {
          "addresDetails.Name": "Mark"
        }
      }
    ])
    

    You can find the mongo playground link for this here. But unwind is usually not preferred as the first stage of the aggregation pipeline either, again because of performance reasons.

    Also please note that the results for these 2 options are different!

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search