MongoDB 之 aggregate $lookup 关联查询 进阶篇

需求:

要对 topics é—®é¢˜è¡¨æ ¹æ® teach_id(教师ID),tips._idï¼ˆé—®é¢˜æ ‡ç­¾ID) 字段进行分ç>>„ç>>Ÿè®¡æ•™å¸ˆçš„答题情况生成报表,所ä>>¥å¾—æ ¹æ® 教师IDï¼Œæ ‡ç­¾ID 关联查询出 æ•™å¸ˆä¿¡æ¯ï¼Œæ ‡ç­¾ä¿¡æ¯ 用作报表展示。

本文基于 MongoDB V3.2 聚合查询语法,V3.6 可使用更多的特性实现

topics 表数据ç>>“构:

{

"_id" : "ffffea46-ab7d-4c19-afa4-fe37709d5300",

"evaluation_type" : 3,

"type" : 3,

"content" : "一般纳税人怎么ç>>“转成本",

"tips" : [

{

"_id" : 1000,

"tip_name" : "会计基础"

}

],

"update_at" : NumberLong("1469801351305"),

"author_id" : 10334093,

"timestamp" : NumberLong("1469714932097"),

"race_time" : NumberLong("1469714947334"),

"teach_id" : 10122995,

"last_reply_content" : "è¿™å°±è¦çœ‹ä½ ç”¨çš„æ˜¯ä>>€ä¹ˆæˆæœ¬è®¡ä>>·æ–¹æ³•。",

"last_reply_at" : NumberLong("1469715279859"),

"end_type" : 2

}

ä>>Žæ•°æ®ç>>“构中可ä>>¥çŸ¥é“第一步操作是:

æ ¹æ® teach_id,tips._id 字段进行分ç>>„,

可得 group(分ç>>„) 语句:

$group:{

_id:{"teacherId":"teach_id","tipId":"tips._id"},

evaluationTypes:{

push:"evaluation_type"

},

sum: {$sum: 1}

}

$push官方文档(https://docs.mongodb.com/manual/reference/operator/update/push/index.html)

$push:可ä>>¥åˆ†ç>>„之后把 evaluation_type 字段值 赋ç>>™ evaluationTypes åŠ å…¥åˆ°åˆ†ç>>„之后的返回值中

$sum官方文档(https://docs.mongodb.com/manual/reference/operator/aggregation/sum/index.html)

$sum:可得到 teach_id,tips._id 都相同的记录条数

使用脚本:

db.getCollection("topics").aggregate([** {

$match:{

"race_time" : {"gte":1522512000000,"lte":1525103999000},

"type":3

}

},

{

$group:{

_id:{"teacherId":"teach_id","tipId":"tips._id"},

evaluationTypes:{

push:"evaluation_type"

},

sum: {$sum: 1}

}

}

])

查询ç>>“果:**

ä>>Žç>>“果可ä>>¥çœ‹å‡º 教师:10706280 åœ¨è¿™ä¸ªæ ‡ç­¾ï¼š1002 下一共抢答了 4 条问题,ä>>¥åŠé—®é¢˜çš„ evaluationTypes(评ä>>·ç±>>型)

一个分ç>>„作为报表的一条记录,所ä>>¥æˆ‘ä>>¬å¾—计算报表的æ€>>记录数(æ€>>行数)total,所ä>>¥å†å¯¹åˆ†å¥½ç>>„çš„è®°å½•è¿›è¡Œæ— 条ä>>¶åˆ†ç>>„(_id: null)**

使用脚本:**

db.getCollection("topics").aggregate([

{

$match:{

"race_time" : {"gte":1525103910000,"lte":1525103999000},

"type":3

}

},

{

$group:{

_id:{"teacherId":"teach_id","tipId":"tips._id"},

evaluationTypes:{

push:"evaluation_type"

},

sum: {$sum: 1}

}

},

{

$group:{

_id: null,

list:{

push:"$ROOT"

},

total: {$sum: 1}

}

}

])

$$ROOT 指定的是分ç>>„前的所有数据,所ä>>¥ list 会把第一次分ç>>„得到的数据都带上

total 是第一次分ç>>„之后的记录数,即一共分了多少ç>>„,之后用作分页æ€>>数

查询ç>>“果:

这里的 group 使用可参考:MongoDB 之 aggregate $group 巧妙运用

教师ID ä>>¥åŠ æ ‡ç­¾ID 等信息包å<<在 list 集合里,所ä>>¥éœ€è¦å¯¹ list 进行扁平化($unwind)操作,可参考:MongoDB 聚合嵌入的数ç>>„(扁平化数据+管道)

使用脚本:**

db.getCollection("topics").aggregate([

{

$match:{

"race_time" : {"gte":1522512000000,"lte":1525103999000},

"type":3

}

},

{

$group:{

_id:{"teacherId":"teach_id","tipId":"tips._id"},

evaluationTypes:{

push:"evaluation_type"

},

sum: {$sum: 1}

}

},

{

$group:{

_id: null,

list:{

push:"$ROOT"

},

total: {$sum: 1}

}

},

{

unwind:"list"

},

{

$sort: {"list.sum": -1}

},

{

$skip: 0

},

{

$limit: 100

}

])

查询ç>>“果:**

扁平化 list é›†åˆæ•°æ®ä¹‹åŽï¼Œå¯æ ¹æ® 教师IDï¼Œæ ‡ç­¾ID 关联查询($lookupï¼‰å‡ºæ•™å¸ˆä¿¡æ¯ï¼Œæ ‡ç­¾ä¿¡æ¯

$lookup:

{

from:"users",

localField:"list._id.teacherId",

foreignField: "_id",

as: "users"

}

$lookup(官方文档--https://docs.mongodb.com/manual/reference/operator/aggregation/lookup/index.html)

3.2版本 åªèƒ½æ ¹æ® localField,foreignField 单条ä>>¶å…³è”,

3.6版本中 关联查询引入 pipeline 管道支持更多更丰富的查询,对应本文会有更好的解决方案。具体使用可ä>>¥æŸ¥çœ‹å®˜æ–¹æ–‡æ¡£

之后便是对数据的多次关联查询,ä>>¥åŠæ‰å¹³åŒ–操作,下面贴上

完整查询脚本:

db.getCollection("topics").aggregate([** {

$match:{

"race_time" : {"gte":1522512000000,"lte":1525103999000},

"type":3

}

},

{

$group:{

_id:{"teacherId":"teach_id","tipId":"tips._id"},

evaluationTypes:{

push:"evaluation_type"

},

sum: {$sum: 1}

}

},

{

$group:{

_id: null,

list:{

push:"$ROOT"

},

total: {$sum: 1}

}

},

{

unwind:"list"

},

{

$sort: {"list.sum": -1}

},

{

$skip: 0

},

{

$limit: 100

},

{

$lookup:

{

from:"users",

localField:"list._id.teacherId",

foreignField: "_id",

as: "users"

}

},

{

$lookup:

{

from:"tip_content",

localField:"list._id.tipId",

foreignField: "_id",

as: "childTip"

}

},

{

$lookup:

{

from:"tip_content",

localField:"childTip.parent_tip_id",

foreignField: "_id",

as: "parentTip"

}

},

{

unwind:"users"

},

{

unwind:"childTip"

},

{

unwind:"parentTip"

},

{

$project:{

"teacherId":"$list._id.teacherId",

"teacherName":"$users.real_name_from_nc",

"tuid":"$users.tuid",

"mobile":"$users.mobile",

"tipId":"$childTip._id",

"tipName":"$childTip.tip_name",

"parentTipId":"$parentTip._id",

"parentTipName":"$parentTip.tip_name",

"sum":"$list.sum",

"total":"$total",

"evaluationTypes":"$list.evaluationTypes",

"_id":0

}

}

])

查询ç>>“果:**


作者:molashaonian

相关推荐
Litluecat2 个月前
2026年6月11日科技热点新闻
科技·量子计算·热点·新闻·每日·速览
Litluecat2 个月前
2026年6月9日科技热点新闻
科技·热点·新闻·每日·速览
Litluecat2 个月前
2026年6月6日科技热点新闻
人工智能·科技·热点·每日
Litluecat2 个月前
2026年6月4日科技热点新闻
科技·推荐·热点·新闻·每日
Litluecat2 个月前
2026年6月5日科技热点新闻
科技·推荐·热点·新闻·每日
Litluecat2 个月前
2026年6月2日科技热点新闻
科技·热点·新闻·每日
Litluecat2 个月前
2026年6月1日科技热点新闻
大数据·人工智能·科技·推荐·热点·新闻·每日
Litluecat2 个月前
2026年5月31日科技热点新闻
人工智能·科技·热点·新闻·每日·速览
Litluecat2 个月前
2026年5月28日科技热点新闻
科技·热点·新闻