例 1
关联关系:
-
accountDSNConfig表:每个account对应的分库的配置信息; -
account表:每个account的具体信息; - 存在关系:
accountDSNConfig.account_id == account.Id。
我现在要把同一库(即 accountDSNConfig.dsn 相同)中的 accountId 统计出来,并且筛选掉未激活的 account。
实现:
db.getCollection('accountDSNConfig').aggregate([
{
"$lookup": {
"from": "account", // the name of collection which to join
"localField": "accountId", // field name in accountDSNConfig
"foreignField": "_id", // the name of the same field value with accountDSNConfig's localField in joined collection
"as": "account" // as an element pushed into this filed
}
},
{"$match": {"account.isDeleted": false, "account.status": "activated"}}, // query in aggregate as usual
{"$group": {_id: "$dsn", "accountIds": {"$push": "$accountId"}}}
])
解释:
- 在
accountDSNConfig用聚合查询 -
$lookup命令- 去
account($lookup.from) 表(外表)中 - 找
本地字段 accountId等于外域字段 _id(accountDSNConfig.accountId == account._id) 的 document - 作为 (
as)account对象添加进查询 stage 中
- 去
-
$match命令- 在当前 stage 中匹配
account.isDeleted: false, account.status: "activated"的 document
- 在当前 stage 中匹配
-
$group命令- 按 document 内字段
dsn进行分组命名为_id字段,将 doc 内accountId字段 push 到名为accountIds的数组内
- 按 document 内字段
例 2
关联关系:
-
account表 -
channel表:每个account下绑定的渠道 - 存在关系:
account._id == channel.accountId
实现:
db.getCollection('channel').aggregate([
{
"$lookup": {
"from": "account",
"localField": "accountId",
"foreignField": "_id",
"as": "account"
}
},
{"$match": {}},
{"$unwind": "$account"},
{"$project": {_id: 0, "accountId": 1, channelId: 1, channelName: "$name", "company": "$account.company" }}
])
解释:
- 在
channel表中 -
$lookup命令- 在外表
account表中 - 查本地字段 accountId 等于 外表字段 _id (
channel.accountId == account._id)的 document - 作为
account对象加入 stage (这个 account 是个数组)
- 在外表
-
$match: 匹配所有 stage 内中的 document (可以删除此行) -
$unwind:由于account对象存的是数组(这里是唯一匹配,所以一定只有一个元素),将它展开出来。(此时 account 本来没有元素的 document 会消失) -
$project:重组此查询的字段名- 格式为:
showField: $originalField -
showField: 0表示按字段名隐藏,1 为显示(此时字段不重命名)。
- 格式为:
注:
-
aggregate中在每一个stage都是可以查看的当前表的结构的,从而可以一步步构建自己想要的结构 - 在 4.0+ version 中可以用下方命令改字段格式
$project: {
_id: {
$toString: "$_id"
}
}
- 日期的格式化用
"workflowCreatedAt": { $dateToString: { format: "%Y-%m-%dT%H:%M:%SZ", date: "$createdAt" } }
例 3
db.getCollection('membershipDiscount').aggregate([
{"$group": {_id: "$accountId", "count": {"$sum": 1}}},
{"$lookup": {
"from": "account",
"localField": "_id",
"foreignField": "_id",
"as": "account"
}},
{"$unwind": "$account"},
{"$project": {"company": "$account.company", count: 1, "_id": 1 }}
])