如何将由ObjectId对和相关集合组成的数组进行聚合

8 浏览
0 Comments

如何将由ObjectId对和相关集合组成的数组进行聚合

我有一个课程集合,我正在为该课程的每个科目分配教师。分配结果保存为一个JSON数组,请参考下面的参考文档。

我正在尝试将两个不同集合中的科目和教师字段与其文档进行匹配。我可以将它们分别获取为两个不同的数组,但无法按照我期望的输出结构获取它们。

教师集合中的文档:

{

_id: ObjectId("5cbee0e37a3c852868ec9797"),

name: "Alister"

}

科目集合中的文档:

{

_id: ObjectId("5cc3f7cc88e95a0c8e8ccd7d"),

name: "English",

code: "EN"

}

我尝试的查询:

Course.aggregate([

{"$match": matchQuery},

{"$lookup": {

"from": "subjects",

"localField": "allotment.subject",

"foreignField": "_id",

"as": "subjectInfo"

}},

{"$lookup": {

"from": "teachers",

"localField": "allotment.teacher",

"foreignField": "_id",

"as": "teacherInfo"}

},

])

该查询的输出:

{

isAssigned: true,

name: "11",

section: "A",

subjectInfo:[

{_id: "5cc3f7cc88e95a0c8e8ccd7d", name:"English", code:"EN"},

{_id: "5cc3f80e88e95a0c8e8ccd7e", name: "Science", code:"SC"}

],

teacherInfo:[

{_id: ObjectId("5cbee0e37a3c852868ec9797"),name: "Alister"},

{ _id: ObjectId("5cbee10c7a3c852868ec9798"),name: "Frank"}

]

}

期望的输出:

{

"_id" : ObjectId("5cc7d72d8e165005cbef939e"),

"isAssigned" : true,

"name" : "11",

"section" : "A",

"allotment" : [

{

"subject" : {

_id: ObjectId("5cc3f7cc88e95a0c8e8ccd7d"),

name: "English",

code: "EN"

},

"teacher" : {

_id: ObjectId("5cbee0e37a3c852868ec9797"),

name: "Alister"

}

},

{

"subject" : {

_id: ObjectId("5cc3f80e88e95a0c8e8ccd7e"),

name: "Science",

code: "SC"

},

"teacher" : {

_id: ObjectId("5cbee10c7a3c852868ec9798"),

name: "Frank"

}

}

]

}

0
0 Comments

这篇文章将介绍如何使用聚合查询在MongoDB中汇总ObjectId对的数组以及相关的集合。

问题的原因是需要将一个包含ObjectId对的数组与相关的集合进行汇总。解决方法是使用聚合查询,首先使用$unwind操作符展开allotment数组,然后使用$lookup操作符关联subject集合,并重复相同步骤关联teachers集合,最后使用$group操作符将它们合并回数组中。

以下是我尝试并成功运行的聚合查询:

Course.aggregate([
    {"$match": matchQuery},
    {
        $unwind: '$allotment'  
    },
    {
        $lookup:{
            "from": "subjects",
            "localField": "allotment.subject",
            "foreignField": "_id",
            "as": "allotment.subject"
        }
    },
    {
        $unwind: '$allotment.subject'  
    },
    {
        "$lookup": {
            "from": "teachers",
            "localField": "allotment.teacher",
            "foreignField": "_id",
            "as": "allotment.teacher"
        }
    },
    {
        $unwind: '$allotment.teacher'  
    },
    { 
        "$group" : {
            "_id" : "$_id", 
            "isAssigned" : {
                "$first" : "$isAssigned"
            }, 
            "name" : {
                "$first" : "$name"
            }, 
            "section" : {
                "$first" : "$section"
            }, 
            "allotment" : {
                "$addToSet" : "$allotment"
            }
        }
    }
])

以上就是如何使用聚合查询在MongoDB中汇总ObjectId对的数组以及相关的集合的方法。通过这个方法,我们可以轻松地将数组中的ObjectId与其他集合中的相关数据关联起来。

0
0 Comments

问题的出现原因是需要通过ObjectId对数组进行聚合,并与相关的集合进行连接。解决方法是使用MongoDB的聚合操作符$lookup,它允许在聚合过程中连接集合。

具体解决方法如下所示:

1. 使用$unwind将数组展开,将每个元素作为独立的文档处理。

2. 使用$lookup操作符连接subjects集合,通过localField和foreignField指定连接的字段,将结果存储在allotment.subject字段中。

3. 使用$lookup操作符连接teachers集合,通过localField和foreignField指定连接的字段,将结果存储在allotment.teacher字段中。

4. 使用$addFields操作符将allotment.subject和allotment.teacher数组中的第一个元素赋值给相应的字段。

5. 使用$group操作符将结果按_id字段进行分组,将isAssigned、name、section和allotment字段的值分别取第一个值,将allotment字段的值存储为数组。

完整的聚合管道如上所示。

这样,通过以上的聚合操作,就可以实现对数组的ObjectId进行聚合,并与相关的集合进行连接。

0
0 Comments

问题出现的原因:

在对ObjectId对数组进行聚合时,需要将其与相关的集合进行关联,但是在使用$lookup操作符时,可能会出现无法正确匹配的问题。

解决方法:

可以在进行关联查询之前,先对数组进行解构(unwind),然后再进行关联查询。这样可以确保每个ObjectId对都能正确匹配到对应的集合。

具体实现代码如下:

Course.aggregate([
    {"$match": matchQuery},
    {"$unwind": "$allotment"},
    {"$lookup": {
        "from": "subjects",
        "localField": "allotment.subject",
        "foreignField": "_id",
        "as": "subjectInfo"
    }},
    {"$lookup": {
        "from": "teachers",
        "localField": "allotment.teacher",
        "foreignField": "_id",
        "as": "teacherInfo"
    }},
])

如果希望在恢复预期格式后重新分组,可以添加以下代码:

{ $group : { 
    _id: "$_id",
    name: {$first: "$name"},
    section: {$first: "$section"},
    isAssigned: {$first: "$isAssigned"},
    allotment: {$push: {teacher: "$teacherInfo.0", subject: "$subjectInfo.0"}}
}}

这里假设teacherInfo和subjectInfo永远不为空,如果不是这种情况,则需要添加$match来过滤空值。

0