1

I have a particular field in my document which has a multilevel nested array structure. The document looks like something this

{
    "_id" : ObjectId("62171b4207476091a17f595f"),
    "data" : [ 
        {
            "id" : "1",
            "content" : [ 
                {
                    "id" : "1.1",
                    "content" : []
                }, 
                {
                    "id" : "1.2",
                    "content" : [ 
                        {
                            "id" : "1.2.1",
                            "content" : [ 
                                {
                                    "id" : "1.2.1.1",
                                    "content" : []
                                }
                            ]
                        }, 
                        {
                            "id" : "1.2.2",
                            "content" : []
                        }
                    ]
                }
            ]
        }
    ]
}

(The ids in my actual data is a random string, I have added a more defined id here just for readability)

In my application code the nesting level is controlled so it won't go more than 5 levels deep.

I need to project a particular object inside one of the deeply nested arrays.

I have all the information needed to traverse the nested structure. For example if I need to fetch the object with id "1.2.2" my input will look something like this:

[{id: 1, index: 0}, {id: 1.2, index: 1}, {id: 1.2.2, index: 1}]

In the above array, each element represents one level of nesting. I have the Id and the index. So in the above example, I know I first need to travel to index 0 at the top level, then inside that to index 1 , then inside that to index 1 again to find my object.

Is there a way I can only get the inner object that I want directly using a query. Or will I need to get the whole "data" field and do the traversal in my application code. I have been unable to figure out any way to construct a query that would satisfy my need.

1 Answer 1

1

Query

  • if you know the path, you can do it using a series of nested
    • $getField
    • $arrayElemAt
  • you can do it in one stage with nested calls, or with many new fields like i did bellow, or with mongodb variables

*i am not sure what output you need, this goes inside to get the 2 using the indexes (if this is not what you need add if you can the expected output)

Test code here

Data

[
  {
    "_id": ObjectId( "62171b4207476091a17f595f"),
    "data": [
      {
        "id": "1",
        "content": [
          {
            "id": "1.1",
            "content": []
          },
          {
            "id": "1.2",
            "content": [
              {
                "id": "1.2.1",
                "content": [
                  {
                    "id": "1.2.1.1",
                    "content": []
                  }
                ]
              },
              {
                "id": "1.2.2",
                "content": [1,2]
              }
            ]
          }
        ]
      }
    ]
  }
]

Query

aggregate(
[{"$set":
  {"c1":
   {"$getField":
    {"field":"content", "input":{"$arrayElemAt":["$data", 0]}}}}},
 {"$set":
  {"c2":
   {"$getField":
    {"field":"content", "input":{"$arrayElemAt":["$c1", 1]}}}}},
 {"$set":
  {"c3": 
   {"$getField":
    {"field":"content", "input":{"$arrayElemAt":["$c2", 1]}}}}},
 {"$project":{"_id":0, "c4":{"$arrayElemAt":["$c3", 1]}}}])

Results

[{
  "c4": 2
}]
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.