MongoDB - 如何聚合深层嵌套数组
MongoDB - How to aggregate with deeply nested arrays
我有以下 MongoDB 结构:
除法Collection:
{
"_id": ObjectId("5b28cab902f28e18b863bd36"),
"name": "Premier League",
...
"teams": [
ObjectId("5b28cab902f28e18b863bd01"),
ObjectId("5b28cab902f28e18b863bd02"),
ObjectId("5b28cab902f28e18b863bd03"),
...
]
...
},
...
团队 Collection:
{
"_id": ObjectId("5b28cab902f28e18b863bd01"),
"name": "Liverpool",
...
"players": [
ObjectId('5b23tmb902f28e18b863bd01'),
ObjectId('5b23tmb902f28e18b863bd02'),
ObjectId('5b23tmb902f28e18b863bd03'),
...
]
...
},
...
玩家Collection:
{
"_id": ObjectId("5b2b9a8bbda339352cc39ec1"),
"name": "Mohamed Salah",
"nationality": [
ObjectId("5b23cn1902f28e18b863bd01"),
ObjectId("5b23cn2902f28e18b863bd02"),
],
...
},
...
国家 Collection:
{
"_id": ObjectId("5b23cn1902f28e18b863bd01"),
"name": "England",
...
},
{
"_id": ObjectId("5b23cn2902f28e18b863bd02"),
"name": "Egypt",
...
},
...
如何使用 MongoDB 聚合($lookup
、$pipeline
等)获得如下结果:
{
"divisions": [
{
"_id": ObjectId("5b28cab902f28e18b863bd36"),
"name": "Premier League",
...
"teams": [
{
"_id": ObjectId("5b28cab902f28e18b863bd01"),
"name": "Liverpool",
...
"players": [
{
"_id": ObjectId("5b23tmb902f28e18b863bd01"),
"name": "Mohamed Salah",
"nationality": [
{
"_id": ObjectId("5b23cn2902f28e18b863bd02"),
"name": "Egypt",
...
},
{
"_id": ObjectId("5b23cn1902f28e18b863bd01"),
"name": "England",
...
}
]
...
},
...
]
},
...
]
},
{
"_id": ObjectId("5b28cab902f28e18b863bd37"),
"name": "Championship",
...
},
...
]
}
我设法进行 first-level 合并:
db.divisions.aggregate([
{
$lookup: {
from: 'teams',
localField: 'teams',
foreignField: '_id',
as: 'teams'
}
},
])
然后我运行陷入困境,所以如果有人能帮助我解决这个问题,我将不胜感激。
您需要 multi-level 嵌套 $lookup
和 pipeline
。
db.division.aggregate([
{
$lookup: {
from: "teams",
let: {
teams: "$teams"
},
pipeline: [
{
$match: {
$expr: {
$in: [
"$_id",
"$$teams"
]
}
}
},
{
$lookup: {
from: "players",
let: {
players: "$players"
},
pipeline: [
{
$match: {
$expr: {
$in: [
"$_id",
"$$players"
]
}
}
},
{
$lookup: {
from: "countries",
localField: "nationality",
foreignField: "_id",
as: "nationality"
}
}
],
as: "players"
}
}
],
as: "teams"
}
}
])
也许有人会有用。也可以使用填充方法合并数据:
db.divisions.find(_id: division_id).populate(
{
path: 'teams',
populate: {
path: 'players',
populate: {
path: 'nationality'
}
}
}
)
我有以下 MongoDB 结构:
除法Collection:
{
"_id": ObjectId("5b28cab902f28e18b863bd36"),
"name": "Premier League",
...
"teams": [
ObjectId("5b28cab902f28e18b863bd01"),
ObjectId("5b28cab902f28e18b863bd02"),
ObjectId("5b28cab902f28e18b863bd03"),
...
]
...
},
...
团队 Collection:
{
"_id": ObjectId("5b28cab902f28e18b863bd01"),
"name": "Liverpool",
...
"players": [
ObjectId('5b23tmb902f28e18b863bd01'),
ObjectId('5b23tmb902f28e18b863bd02'),
ObjectId('5b23tmb902f28e18b863bd03'),
...
]
...
},
...
玩家Collection:
{
"_id": ObjectId("5b2b9a8bbda339352cc39ec1"),
"name": "Mohamed Salah",
"nationality": [
ObjectId("5b23cn1902f28e18b863bd01"),
ObjectId("5b23cn2902f28e18b863bd02"),
],
...
},
...
国家 Collection:
{
"_id": ObjectId("5b23cn1902f28e18b863bd01"),
"name": "England",
...
},
{
"_id": ObjectId("5b23cn2902f28e18b863bd02"),
"name": "Egypt",
...
},
...
如何使用 MongoDB 聚合($lookup
、$pipeline
等)获得如下结果:
{
"divisions": [
{
"_id": ObjectId("5b28cab902f28e18b863bd36"),
"name": "Premier League",
...
"teams": [
{
"_id": ObjectId("5b28cab902f28e18b863bd01"),
"name": "Liverpool",
...
"players": [
{
"_id": ObjectId("5b23tmb902f28e18b863bd01"),
"name": "Mohamed Salah",
"nationality": [
{
"_id": ObjectId("5b23cn2902f28e18b863bd02"),
"name": "Egypt",
...
},
{
"_id": ObjectId("5b23cn1902f28e18b863bd01"),
"name": "England",
...
}
]
...
},
...
]
},
...
]
},
{
"_id": ObjectId("5b28cab902f28e18b863bd37"),
"name": "Championship",
...
},
...
]
}
我设法进行 first-level 合并:
db.divisions.aggregate([
{
$lookup: {
from: 'teams',
localField: 'teams',
foreignField: '_id',
as: 'teams'
}
},
])
然后我运行陷入困境,所以如果有人能帮助我解决这个问题,我将不胜感激。
您需要 multi-level 嵌套 $lookup
和 pipeline
。
db.division.aggregate([
{
$lookup: {
from: "teams",
let: {
teams: "$teams"
},
pipeline: [
{
$match: {
$expr: {
$in: [
"$_id",
"$$teams"
]
}
}
},
{
$lookup: {
from: "players",
let: {
players: "$players"
},
pipeline: [
{
$match: {
$expr: {
$in: [
"$_id",
"$$players"
]
}
}
},
{
$lookup: {
from: "countries",
localField: "nationality",
foreignField: "_id",
as: "nationality"
}
}
],
as: "players"
}
}
],
as: "teams"
}
}
])
也许有人会有用。也可以使用填充方法合并数据:
db.divisions.find(_id: division_id).populate(
{
path: 'teams',
populate: {
path: 'players',
populate: {
path: 'nationality'
}
}
}
)