如何在MongoDB中链接左联接?

时间:2019-08-27 12:40:56

标签: mongodb

我正在尝试在MongoDB中执行链式左联接。我可以使用$lookupusers集合加入到employee集合。但是,如果我想与title再参加一次,那将会失败,换句话说,第二个.aggregate([{ $lookup }])会失败。此练习的目的是显示John在使用中间集合(称为employee)时使用的是标题前缀Mr.,Jane在使用标题的前缀Mrs.。那么我该怎么做,或者我做错了什么?

db.users.drop();
db.users.insert({name:"John"});
db.users.insert({name:"Jane"});

db.title.drop();
db.title.insert({prefix:"Mr."});
db.title.insert({prefix:"Mrs."});

db.getCollection('users').find({});
db.getCollection('title').find({});

db.employee.drop();
db.employee.insert({userid:ObjectId("5d6522449b9bc50473af4b4f"), titleid:ObjectId("5d6522449b9bc50473af4b51")});
db.employee.insert({userid:ObjectId("5d6522449b9bc50473af4b50"), titleid:ObjectId("5d6522449b9bc50473af4b52")});
db.getCollection('employee').find({});

db.users.aggregate
([{
   $lookup:
     {
       from: 'employee',
       localField: '_id',
       foreignField: 'userid',
       as: 'R'
     }
   },
]).aggregate
([{
   $lookup:
     {
       from: 'title',
       localField: '_id',
       foreignField: R[0].titleid,
       as: 'T'
     }
   },
]);

2 个答案:

答案 0 :(得分:3)

您在这里做的错误是将另一个查询附加到第一个查询的结果上,这将不起作用。

我认为您应该在员工集合上写聚合,而不是看起来更干净的用户集合。

无论如何,我已经根据您的问题写出了正确的查询,并汇总了用户集合

尝试一下:

db.users.aggregate([
{$lookup: {
    from: "employee",
    localField: "_id",
    foreignField: "userid",
    as: "R"
}},
{$unwind: "$R"},
{$lookup: {
    from: "title",
    localField: "R.titleid",
    foreignField: "_id",
    as: "T"
}},
{$unwind: "$T"},
{$project: {name: 1, title: "$T.prefix", _id: 0} }
])

这将输出如下文件:

{ "name" : "John", "title" : "Mr." }
{ "name" : "Jane", "title" : "Mrs." }

最后一个$ project阶段是可选的。您可以忽略它,但是输出将非常混乱。

答案 1 :(得分:0)

以下查询可以为我们提供预期的输出:

db.users.aggregate([
    {
        $lookup:{
            "from":"employee",
            "localField":"_id",
            "foreignField":"userid",
            "as":"employeeLookup"
        }
    },
    {
        $unwind:"$employeeLookup"
    },
    {
        $lookup:{
            "from":"title",
            "localField":"employeeLookup.titleid",
            "foreignField":"_id",
            "as":"titleLookup"
        }
    },
    {
        $unwind:"$titleLookup"
    },
    {
        $project:{
            "_id":0,
            "name":{
                $concat:[
                    "$titleLookup.prefix",
                    " ",
                    "$name"
                ]
            }
        }
    }
]).pretty()

数据集:

用户:

{ "_id" : ObjectId("5d6525f922a848de552bdcf6"), "name" : "John" }
{ "_id" : ObjectId("5d6525fa22a848de552bdcf7"), "name" : "Jane" }

标题:

{ "_id" : ObjectId("5d6525fa22a848de552bdcf8"), "prefix" : "Mr." }
{ "_id" : ObjectId("5d6525fb22a848de552bdcf9"), "prefix" : "Mrs." }

员工:

{
    "_id" : ObjectId("5d65265422a848de552bdcfa"),
    "userid" : ObjectId("5d6525f922a848de552bdcf6"),
    "titleid" : ObjectId("5d6525fa22a848de552bdcf8")
}
{
    "_id" : ObjectId("5d65265422a848de552bdcfb"),
    "userid" : ObjectId("5d6525fa22a848de552bdcf7"),
    "titleid" : ObjectId("5d6525fb22a848de552bdcf9")
}

输出:

{ "name" : "Mr. John" }
{ "name" : "Mrs. Jane" }