mongodbmongodb-queryaggregation-frameworktree-structure

MongoDB recusrive lookup query


I have a list of documents in a MongoDB with the following structure:

{
  'name': 'A',
  'friends': ['B', 'C']
},
{
  'name': 'B',
  'friends': ['A']
},
{
  'name': 'C',
  'friends': ['A']
},
{
  'name': 'D',
  'friends': []
},
{
  'name': 'E',
  'friends': ['C']
}

I want to recursively find the total group of friends of a given Person, e.g.

Friends of A: ['B', 'C', 'E']

Is this possible using the aggregation framework?


Solution

  • You can do $graphLookup if you are using mongo 3.4+, it is to do hierarchical join on the self collection

    db.frnds.aggregate([
        {$match : {'name': 'A'}},
        {
           $graphLookup: {
              from: "frnds",
              startWith: "$name",
              connectFromField: "name",
              connectToField: "friends",
              as: "friends"
           }
        },
        {$addFields : { friends : {$setUnion : [{$filter : {input : "$friends.name", as : "friend" , cond : {$ne : ["$name", "$$friend"]}}}] }}}
    ])
    

    collection

    > db.frnds.find()
    { "_id" : ObjectId("5a7e694580aae386f73cf0f5"), "name" : "A", "friends" : [ "B", "C" ] }
    { "_id" : ObjectId("5a7e694580aae386f73cf0f6"), "name" : "B", "friends" : [ "A" ] }
    { "_id" : ObjectId("5a7e694580aae386f73cf0f7"), "name" : "C", "friends" : [ "A" ] }
    { "_id" : ObjectId("5a7e694580aae386f73cf0f8"), "name" : "D", "friends" : [ ] }
    { "_id" : ObjectId("5a7e694580aae386f73cf0f9"), "name" : "E", "friends" : [ "C" ] }
    

    result

    { "_id" : ObjectId("5a7e694580aae386f73cf0f5"), "name" : "A", "friends" : [ "B", "C", "E" ] }