Blog

  • How To Use GraphLookup In Mongodb

    Posted by Vipul Pandey | Last Updated: 02-Apr-18

    MongoDB has added a new feature in its version 3.4 $graphLookup, Its is an extended version of $lookup and has enhanced capabilities which are used to perform a recursive search on a collection in an array with multiple values/fields.

    To understands this lets take an example ,I am going to add 5 records of employees with  the Details (Array Supervisors) which will contains the _id's of Supervisors

    db.persons.insertMany([
      { _id: 11, firstName: 'Vipul', Supervisors: [13,15] },
      { _id: 12, firstName: 'Maneesh'},
      { _id: 13, firstName: 'Rijul', Supervisors: [12] },
      { _id: 14, firstName: 'Pulkit', Supervisors: [13] },
      { _id: 15, firstName: 'Anil', Supervisors: [13] }
    ]);
    { "acknowledged" : true, "insertedIds" : [ 11, 12, 13, 14, 15 ] }
    

    To view All records :

    db.persons.find()
    { "_id" : 11, "firstName" : "Vipul", "Supervisors" : [ 13, 15 ] }
    { "_id" : 12, "firstName" : "Maneesh" }
    { "_id" : 13, "firstName" : "Rijul", "Supervisors" : [ 12 ] }
    { "_id" : 14, "firstName" : "Pulkit", "Supervisors" : [ 13 ] }
    { "_id" : 15, "firstName" : "Anil", "Supervisors" : [ 13 ] }
    

    Now if we want to get users with the details of the Supervisors we can use $graphLookup on Supervisors array in the following form

    db.persons.aggregate( [
       {
          $graphLookup: {
             from: "persons",
             startWith: "$Supervisors",
             connectFromField: "Supervisors",
             connectToField: "_id",
             as: "supervisors"
          }
       }
    ])

    { "_id" : 11, "firstname" : "Vipul", "Supervisors" : [1 3, 15 ], "supervisors" : [ { "_id" : 12, "firstname" : "Maneesh" }, { "_id" :1 5, "firstname" : "Anil", "firstname" : [1 3 ] }, { "_id" : 13, "firstname" : "Rijul", "Supervisors" : [ 12 ] } ] }

    { "_id" : 12, "name" : "Maneesh", "Supervisors" : [ ] }

    { "_id" : 13, "name" : "Rijul", "Supervisors" : [ 12 ], "supervisors" : [ { "_id" : 12, "name" : "Maneesh" } ] }

    { "_id" : 14, "name" : "Pulkit", "Supervisors" : [ 13 ], "supervisors" : [ { "_id" : 12, "name" : "Maneesh" }, { "_id" : 13, "name" : "Rijul", "Supervisors" : [1 2 ] } ] }

    { "_id" : 15, "name" : "Anil", "Supervisors" : [ 13 ], "Supervisors" : [ { "_id" : 12, "name" : "Maneesh" }, { "_id" : 13, "name" : "Rijul", "Supervisors" : [ 12 ] } ] }

    1. from: specify the collection from which you need to search, It can be used in same collection or in different as well
    2. startWith: Name of Array
    3. connectFromField: field of Array
    4. connectToField: from which field It will match
    5. as: Name of array in which we need our response to get only name of managers we can use $project which will return only specific property of Supervisors array
    db.users.aggregate([{ $graphLookup: {from: "users",startWith: "$Supervisors",connectFromField: "Supervisors",connectToField: "_id",as: "Supervisors"}},
                        {"$project":{"_id":1,"name":1,"Supervisors.name":1}}])
    It will give us 
    { "_id" : 11, "name" : "Vipul", "Supervisors" : [ { "name" : "Maneesh" }, { "name" : "Anil" }, { "name" : "Rijul" } ] }
    { "_id" : 12, "name" : "Maneesh", "Supervisors" : [ ] }
    { "_id" : 13, "name" : "Rijul", "Supervisors" : [ { "name" : "Maneesh" } ] }
    { "_id" : 14, "name" : "Pulkit", "Supervisors" : [ { "name" : "Maneesh" }, { "name" : "Rijul" } ] }
    { "_id" : 15, "name" : "Anil", "Supervisors" : [ { "name" : "Maneesh" }, { "name" : "Rijul" } ] }
    

    Point to Ponder 

    1. The $graphLookup stage must stay within the 100 megabyte memory limit.
    2. User Vipul has only 2 Supervisors ([13,15]) but the response is contained Name of 3 Supervisors with Rijul, Maneesh, and Anil, Its due to the fact it is searching a recursive search in the array. I will describe It in next blog how to get only Level 1 Supervisors of users, Keep reading.

Tags: mongodb