2

Consider the structure like this:

enter image description here

class Group {
  _id: ObjectId
  subGroups: ObjectId[]
  name: string
  info: string
}

A document for Group A in the database should be...

_id: ObjectId("6092387f9c69970c20fe648a")
subGroups: [
  ObjectId("6092387f9c69970c20fe648b"),  // Group B
  ObjectId("6092387f9c69970c20fe648c"), // Group C
],
name: "Group A",
info: "..."

How can I query in the mongodb to get all children including itself?

For example,

Query for A: Output A, B, C, D, E, F, G, H, I, J

Query for B: Output D, E

James Fu
  • 444
  • 1
  • 8
  • 21

1 Answers1

2

What you want to use is called $graphLookup, it recursively iterates until no more matches are found, like so:

db.collection.aggregate([
  {
    $match: {
      "name": "Group A"
    }
  },
  {
    $graphLookup: {
      from: "collection",
      startWith: "$subGroups",
      connectFromField: "subGroups",
      connectToField: "_id",
      as: "groupHierarchy",
      
    }
  },
  {
    $project: {
      result: {
        "$concatArrays": [
          [
            "$name"
          ],
          {
            $map: {
              input: "$groupHierarchy",
              as: "group",
              in: "$$group.name"
            }
          }
        ]
      }
    }
  }
])

Mongo Playground

Tom Slabbaert
  • 21,288
  • 10
  • 30
  • 43
  • Is it possible to get the list of groups (the whole document) instead of only name? – James Fu May 05 '21 at 08:44
  • Yea, in the final projection stage you can see i return just the names as that was your requested output, you can just delete it and get the full documents. – Tom Slabbaert May 05 '21 at 08:46
  • If I remove the project stage, I found the Group A will be missing in the groupHierarchy. How can I add it to the final result? – James Fu May 05 '21 at 09:02
  • https://mongoplayground.net/p/-twcVhPwT9a for example, you decide the structure you want and use some structure manipulation to achieve it. – Tom Slabbaert May 05 '21 at 09:04