Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongodb graphLookup

Since MongoDB recently introduced graphLookup, I was trying to find if that can hold a simple social relationship graph. I currently use neo4j just for this purpose.

I understand graphLookup as a recursive search, it just go deeper thru the 'connectFromField' of each document.

Though I am able to do the basic stuff, I want to give more properties for each relation. For instance, the first example here:(employees and reporting hierarchy)

https://docs.mongodb.com/manual/reference/operator/aggregation/graphLookup/

{ "_id" : 2, "name" : "Eliot", "reportsTo" : "Dev" }

If I need to add a start date to the 'reportsTo' value, something like this:

{ "_id" : 2, "name" : "Eliot", "reportsTo" : {"name": "Dev", "from": "date"  } }

I am afraid this is not supported.

I would like to know if someone has used the MongoDB this way.

like image 986
w3dev Avatar asked Dec 19 '22 11:12

w3dev


1 Answers

Say we've got the following documents inserted:

> db.employees.insertMany([
... { "_id" : 1, "name" : "Dev" },
... { "_id" : 2, "name" : "Eliot", "reportsTo" : { name: "Dev", "from": ISODate("2016-01-01T00:00:00.000Z") } },
... { "_id" : 3, "name" : "Ron", "reportsTo" : { name: "Eliot", "from": ISODate("2016-01-01T00:00:00.000Z") } },
... { "_id" : 4, "name" : "Andrew", "reportsTo" : { name: "Eliot", "from": ISODate("2016-01-01T00:00:00.000Z") } },
... { "_id" : 5, "name" : "Asya", "reportsTo" : { name: "Ron", "from": ISODate("2016-01-01T00:00:00.000Z") } },
... { "_id" : 6, "name" : "Dan", "reportsTo" : { name: "Andrew", "from": ISODate("2016-01-01T00:00:00.000Z") } },
... ]);
{ "acknowledged" : true, "insertedIds" : [ 1, 2, 3, 4, 5, 6 ] }

We then can just use the . to get a field from an embedded document using the following aggregation query:

db.employees.aggregate([
{
   $graphLookup: {
      from: "employees",
      startWith: "Eliot",
      connectFromField: "reportsTo.name",
      connectToField: "name",
      as: "reportingHierarchy"
   }
}
])

Which will then return us the following result:

{
        "_id" : 1,
        "name" : "Dev",
        "reportingHierarchy" : [
                {
                        "_id" : 1,
                        "name" : "Dev"
                },
                {
                        "_id" : 2,
                        "name" : "Eliot",
                        "reportsTo" : {
                                "name" : "Dev",
                                "from" : ISODate("2016-01-01T00:00:00Z")
                        }
                }
        ]
}
{
        "_id" : 2,
        "name" : "Eliot",
        "reportsTo" : {
                "name" : "Dev",
                "from" : ISODate("2016-01-01T00:00:00Z")
        },
        "reportingHierarchy" : [
                {
                        "_id" : 1,
                        "name" : "Dev"
                },
                {
                        "_id" : 2,
                        "name" : "Eliot",
                        "reportsTo" : {
                                "name" : "Dev",
                                "from" : ISODate("2016-01-01T00:00:00Z")
                        }
                }
        ]
}
{
        "_id" : 3,
        "name" : "Ron",
        "reportsTo" : {
                "name" : "Eliot",
                "from" : ISODate("2016-01-01T00:00:00Z")
        },
        "reportingHierarchy" : [
                {
                        "_id" : 1,
                        "name" : "Dev"
                },
                {
                        "_id" : 2,
                        "name" : "Eliot",
                        "reportsTo" : {
                                "name" : "Dev",
                                "from" : ISODate("2016-01-01T00:00:00Z")
                        }
                }
        ]
}
{
        "_id" : 4,
        "name" : "Andrew",
        "reportsTo" : {
                "name" : "Eliot",
                "from" : ISODate("2016-01-01T00:00:00Z")
        },
        "reportingHierarchy" : [
                {
                        "_id" : 1,
                        "name" : "Dev"
                },
                {
                        "_id" : 2,
                        "name" : "Eliot",
                        "reportsTo" : {
                                "name" : "Dev",
                                "from" : ISODate("2016-01-01T00:00:00Z")
                        }
                }
        ]
}
{
        "_id" : 5,
        "name" : "Asya",
        "reportsTo" : {
                "name" : "Ron",
                "from" : ISODate("2016-01-01T00:00:00Z")
        },
        "reportingHierarchy" : [
                {
                        "_id" : 1,
                        "name" : "Dev"
                },
                {
                        "_id" : 2,
                        "name" : "Eliot",
                        "reportsTo" : {
                                "name" : "Dev",
                                "from" : ISODate("2016-01-01T00:00:00Z")
                        }
                }
        ]
}
{
        "_id" : 6,
        "name" : "Dan",
        "reportsTo" : {
                "name" : "Andrew",
                "from" : ISODate("2016-01-01T00:00:00Z")
        },
        "reportingHierarchy" : [
                {
                        "_id" : 1,
                        "name" : "Dev"
                },
                {
                        "_id" : 2,
                        "name" : "Eliot",
                        "reportsTo" : {
                                "name" : "Dev",
                                "from" : ISODate("2016-01-01T00:00:00Z")
                        }
                }
        ]
}

We can then also use the rest of the aggregation pipeline to do any other manipulations:

db.employees.aggregate([

   { $match: { "reportsTo.from": { $gt: ISODate("2016-01-01T00:00:00Z") } } },
   { $graphLookup: { ... } },
   { $project: { ... }
]);

See https://docs.mongodb.com/v3.2/reference/operator/aggregation-pipeline/ for pipeline stages.

like image 187
Kevin Smith Avatar answered Jan 07 '23 20:01

Kevin Smith