根据学生 ID 聚合多个集合
Posted
技术标签:
【中文标题】根据学生 ID 聚合多个集合【英文标题】:Aggregate multiple collections based on student Id 【发布时间】:2019-04-24 06:49:48 【问题描述】:我正在尝试根据学生 ID 在 MongoDB 中聚合 2 个集合。一个集合包含学生个人信息,另一个集合包含学生日志。问题是数据在数组中,这就是我认为我的聚合不起作用的原因。任何帮助将不胜感激。
学生收藏
"_id" : ObjectId("(Object ID here"),
"data" : [
"name" : "John",
"id" : 1
,
"name" : "Sandy",
"id" : 2
]
日志收集
"_id" : ObjectId("(Object ID here"),
"logs" : [
"studentId" : 1,
"activity" : "11112,334,123"
,
"studentId" : 2,
"activity" : "11112,334,123"
]
这是我尝试过的:
dbo.collection("student").aggregate([
"$lookup":
"localField": "data.id",
"from": "logs",
"foreignField": "logs.studentId",
"as": "studentInfo"
]).toArray(function(err, results)
console.log(results);
);
预期结果:
studentinfo:
id: 1,
name: "John",
activity" : "11112,334,123"
【问题讨论】:
你使用的是什么版本的mongodb?你想要什么输出? 有什么理由这样存储数据?通常每个学生都是自己的文件 @AnthonyWinzlet 我想获得学生日志和个人信息的联合结果 @Bajal true 但这是一个更大的应用程序的一部分,学生目前没有那么多信息 @HeelMega 你能粘贴给定输入的预期输出吗? 【参考方案1】:您可以在 mongodb 3.6
中使用以下聚合所以基本上你的外部字段是一个数组,你需要将$lookup
与管道一起使用到$unwind
$lookup
管道内的外部数组并匹配相应的ids
。
db.students.aggregate([
"$lookup":
"from": "logs",
"let": "dataId": "$data.id" ,
"pipeline": [
"$unwind": "$logs" ,
"$match": "$expr": "$in": ["$logs.studentId", "$$dataId"] ,
"$replaceRoot": "newRoot": "$logs"
],
"as": "students"
])
或者使用它来合并两个数组
db.students.aggregate([
"$lookup":
"from": "logs",
"let": "dataId": "$data.id" ,
"pipeline": [
"$unwind": "$logs" ,
"$match": "$expr": "$in": ["$logs.studentId", "$$dataId"] ,
"$replaceRoot": "newRoot": "$logs"
],
"as": "students"
,
"$project":
"students":
"$map":
"input": "$students",
"in":
"studentId": "$$this.studentId",
"activity": "$$this.activity",
"name": "$arrayElemAt": ["$data.name", "$indexOfArray": ["$data.id", "$$this.studentId"] ]
])
输出
[
"students": [
"activity": "11112,334,123",
"name": "John",
"studentId": 1
,
"activity": "11112,334,123",
"name": "Sandy",
"studentId": 2
]
]
【讨论】:
第一个查询中的dataId来自哪里?dataId
是我们在let
表达式中取的变量。哪个是你的localField
。以上是关于根据学生 ID 聚合多个集合的主要内容,如果未能解决你的问题,请参考以下文章