0

I have a list of documents which contains another list as a child, which also have the = children containing same document type and it also have children array and so on. My question is I want to search document by Id which might be the parent or in the children list or its grandchildren list or grand grand child list and deeper. How can I search for that in MongoDB?

This is what my tree structure likes :

[
  {
    "_id": {
      "$oid": "632fcf89b79445a59228851a"
    },
    "label": "Cow",
    "children": []
  },
  {
    "_id": {
      "$oid": "632fcf8db79445a59228851b"
    },
    "label": "Rat",
    "children": [
      {
        "_id": {
          "$oid": "632fd378d7316cdaf81c18a7"
        },
        "label": "Cub",
        "children": [
            {
              "_id": {
                 "$oid": "632fd378d7316cdaf81c18a8"
              },
              "label": "Deer",
              "children": []
            }
        ]
      }
    ]
  },
  {
    "_id": {
      "$oid": "632fcf8eb79445a59228851c"
    },
    "label": "Lion",
    "children": []
  }
]

This is what I tried but it adds element upto 1 level, however it does not search the children list exhaustively.

var toInsert = { _id: ObjectId(), "label" : "Tiger", "children": []};

db.animal.findOneAndUpdate(
    {"_id": ObjectId("632fd378d7316cdaf81c18a7")},
    {
      $push: {
        children: toInsert
      }
    }
);

db.collection.find({});
Jay Dangar
  • 3,271
  • 1
  • 16
  • 35
  • If I understand what you want, using your current data model you would need to recursively search the `"children"` arrays for each new update. Would a flatter data model with a single `"parents"` and `"children"` array work better? – rickhg12hs Sep 25 '22 at 14:51
  • It works better but I also need to return the tree like structure as it's one of my requirnment. That's why I choose mongoDB. – Jay Dangar Sep 25 '22 at 15:04
  • [`$graphLookup`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/graphLookup/) could create the tree structure from the flattened collection. – rickhg12hs Sep 25 '22 at 15:16
  • ... doing something like this [mongoplayground.net "parent" example](https://mongoplayground.net/p/ihPRDZy2hhL) or [mongoplayground.net "children" example](https://mongoplayground.net/p/Kyben2bPANS). – rickhg12hs Sep 25 '22 at 15:43
  • @rickhg12hs I doubt $graphlookup can return nested structure of arbitrary depth, if I get OP's comment. Am happy to be wrong on this account and will award a bounty to https://stackoverflow.com/questions/73845955/mongodb-aggregation-how-to-model-a-collection-to-return-a-tree-structure tho. – Alex Blex Sep 25 '22 at 16:06
  • @AlexBlex My mongoplayground.net examples above retrieve the full depth. – rickhg12hs Sep 25 '22 at 16:10
  • @rickhg12hs Your example do not dereference second level children and return only `{"_id": ObjectId("632fd378d7316cdaf81c18a8")}` instead of the full object. Sorry, I don't want to steal the show here, but encourage you to answer the related question. – Alex Blex Sep 25 '22 at 16:17
  • I think it's better to use relational database for this kind of scenario, this documentation provides the answer for the same: https://www.baeldung.com/cs/storing-tree-in-rdb – Jay Dangar Sep 25 '22 at 16:19
  • @AlexBlex The output of [mongoplayground.net "children" example](https://mongoplayground.net/p/Kyben2bPANS) shows the full object at `"level": NumberLong(1)` in the `"children"` array. – rickhg12hs Sep 25 '22 at 16:23
  • @JayDangar If you are flexible to radially change db engine, I would recommend Rick's approach. Use $graphlookup to get the documents and build the tree on the application level. It would be simpler than change nonsql database to sql. Mongo supports hierarchical structures, the limitation is only on shaping the response to the tree-like structure. – Alex Blex Sep 25 '22 at 16:38

0 Answers0