mongodb - 如何使用 $lookup 和 $in mongodb 聚合

标签 mongodb mongodb-query aggregation-framework

Colleges

{
    "_id" : ObjectId("5cd42b5c65b41027845938ae"),
    "clgID" : "100",
    "name" : "Vivekananda"
},

{
    "_id" : ObjectId("5cd42b5c65b41027845938ad"),
    "clgID" : "200",
    "name" : "National"
}

点:1 => 从 Colleges 集合中获取所有 clgID

Subjects:

{
    "_id" : ObjectId("5cd42c2465b41027845938b0"),
    "name" : "Hindi",
    "members" : {
        "student" : [
            "123"
        ]
    },
    "college" : {
        "collegeID" : "100"
    }
},

{
    "_id" : ObjectId("5cd42c2465b41027845938af"),
    "name" : "English",
    "members" : {
        "student" : [
            "456",
            "789"
        ]
    },
    "college" : {
        "collegeID" : "100"
    }
}

Point : 2 => Subjects 集合我们将 clgID 映射到 college.collegeID 下,Subjects 集合我们需要根据 members.student 获取 clgID 的值。

CollegeProducts

{
    "_id" : "123",
    "StudentProdcutID" : "123",
    "StudentID" : "FF80",
    "CID" : "Facebook"
},
{
    "_id" : "456",
    "StudentProdcutID" : "456",
    "StudentID" : "FF81",
    "CID" : "Facebook"
},
{
    "_id" : "789",
    "StudentProdcutID" : "789",
    "StudentID" : "FF82",
    "CID" : "Facebook"
}

Point : 3 => CollegeProducts 集合我们在 members.student 下映射 StudentProdcutID 值,CollegeProducts 集合我们需要获取 StudentID 中的值。 CollegeProducts 集合,我们需要检查条件 CID 应该是 Facebook 并根据 StudentID 获取 members.student 的值。

UserDetails

{
    "name" : "A",
    "StudentID" : "FF80"

},
{
    "name" : "B",
    "StudentID" : "FF81"
},
{
    "name" : "C",
    "StudentID" : "FF82"
}

Point : 3 => UserDetails 集合我们在 StudentID 下映射了 StudentID 值,UserDetails 集合我们需要获取 name 的值。

Expected Output:

{
"collegeName" : "National",
"StudentName" : "A"
},
{
"collegeName" : "National",
"StudentName" : "B"
},
{
"collegeName" : "National",
"StudentName" : "C"
}

My Code

 db.Colleges.aggregate([
  { "$match": { "clgID": { "$in": ["100", "200"] }}},
  { "$lookup": {
    "from": "Subjects",
    "localField": "clgID",
    "foreignField": "college.collegeID",
    "as": "clg"
  }},
  { "$unwind": { "path": "$clg", "preserveNullAndEmptyArrays": true }},
  { "$group": {
    "_id": { "clgId": "$clg.college.collegeID", "_id": "$_id" },
    "groupDetails": { "$push": "$clg.members.student" },
    "clgName": { "$first": "$name" }
  }},
  { "$project": {
    "_id": "$_id._id",
    "clgName": 1,
    "groupDetails": {
      "$reduce": {
        "input": "$groupDetails",
        "initialValue": [],
        "in": { "$concatArrays": ["$$this", "$$value"] }
      }
    }
  }}
])

我没有得到预期的输出,请帮助我。我正在使用 mongodb version3.4

最佳答案

如果您希望每个输出都是一个用户,则不必费心进行分组,您只是在做双倍的工作。

将您的查询更改为:

    { 
        "$match" : {
            "clgID" : {
                "$in" : [
                    "100", 
                    "200"
                ]
            }
        }
    }, 
    { 
        "$lookup" : {
            "from" : "Subjects", 
            "localField" : "clgID", 
            "foreignField" : "college.collegeID", 
            "as" : "clg"
        }
    }, 
    { 
        "$unwind" : {
            "path" : "$clg", 
            "preserveNullAndEmptyArrays" : true
        }
    }, 
    { 
        "$unwind" : {
            "path" : "$clg.members.student", 
            "preserveNullAndEmptyArrays" : true
        }
    }, 
    { 
        "$project" : {
            "collegeName" : "$name", 
            "student" : "$clg.members.student"
        }
    }
], 

现在,第二次展开时,每个对象都包含大学名称和 -ONE- 学生,因此我们现在需要做的就是以所需的形式进行项目。

编辑:根据请求进行完整查询

    { 
        "$match" : {
            "clgID" : {
                "$in" : [
                    "100", 
                    "200"
                ]
            }
        }
    }, 
    { 
        "$lookup" : {
            "from" : "Subjects", 
            "localField" : "clgID", 
            "foreignField" : "college.collegeID", 
            "as" : "clg"
        }
    }, 
    { 
        "$unwind" : {
            "path" : "$clg", 
            "preserveNullAndEmptyArrays" : true
        }
    }, 
    { 
        "$unwind" : {
            "path" : "$clg.members.student", 
            "preserveNullAndEmptyArrays" : true
        }
    }, 
    { 
        "$lookup" : {
            "from" : "CollegeProducts", 
            "localField" : "clg.members.student", 
            "foreignField" : "StudentProdcutID", 
            "as" : "clgproduct"
        }
    }, 
    {   // can skip this unwind if theres always only one match.
        "$unwind" : {
            "path" : "$clgproduct", 
            "preserveNullAndEmptyArrays" : true
        }
    }, 
    { 
        "$match" : {
            "clgproduct.CID" : "Facebook"
        }
    }, 
    { 
        "$lookup" : {
            "from" : "UserDetails", 
            "localField" : "clgproduct.StudentID", 
            "foreignField" : "StudentID", 
            "as" : "student"
        }
    }, 
    {   // can skip this unwind if theres always only one user matched.
        "$unwind" : {
            "path" : "$student", 
            "preserveNullAndEmptyArrays" : true
        }
    }, 
    { 
        "$project" : {
            "collegeName" : "$name", 
            "student" : "$student.name"
        }
    }
], 

关于mongodb - 如何使用 $lookup 和 $in mongodb 聚合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56073497/

相关文章:

MongoDB如何通过搜索混合模式字段来查找文档?

node.js - 使用聚合框架转换具有两个嵌套文档的文档

javascript - 通过输入表单查询 MongoDB

java - Spring 数据: MongoDB: Aggregation: group by nested object

mongodb - 聚合和运算符的区别

mongodb - 计算重复值的出现次数

arrays - MongoDB 中每年和每月的聚合

MongoDB 开源与 MongoDB 企业版

java - 无法通过本地计算机上的 Java 代码连接到谷歌计算引擎上的 mongodb 服务器

java - 如何覆盖 SPRING BOOT 自动配置提供的默认值