【问题标题】:Mongodb graphLookupMongodb graphLookup
【发布时间】:2016-12-06 07:13:24
【问题描述】:

自从 MongoDB 最近引入了 graphLookup,我试图找出它是否可以保存一个简单的社交关系图。我目前使用 neo4j 只是为了这个目的。

我将 graphLookup 理解为递归搜索,它只是通过每个文档的“connectFromField”进行更深入的搜索。

虽然我能够做基本的事情,但我想为每个关系提供更多属性。例如这里的第一个例子:(员工和报告层次结构)

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

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

如果我需要为“reportsTo”值添加开始日期,如下所示:

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

恐怕不支持。

我想知道是否有人以这种方式使用过 MongoDB。

【问题讨论】:

    标签: mongodb aggregation-framework


    【解决方案1】:

    假设我们插入了以下文档:

    > 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 ] }
    

    然后,我们可以使用 . 使用以下聚合查询从嵌入文档中获取字段:

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

    这将返回以下结果:

    {
            "_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")
                            }
                    }
            ]
    }
    

    然后我们还可以使用聚合管道的其余部分进行任何其他操作:

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

    有关流水线阶段,请参阅 https://docs.mongodb.com/v3.2/reference/operator/aggregation-pipeline/

    【讨论】:

    • 如何投影报告层次结构?如果我不想从报告层次结构中的项目中看到怎么办?就我而言,文档很大,项目很多。
    • @LuffyCyliu 只需使用 $project 管道将其投影到另一个模型中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-08
    • 1970-01-01
    • 2020-11-08
    • 1970-01-01
    相关资源
    最近更新 更多