mongodb - MongoDB:两个集合之间的多个 $lookup
问题描述
我有两个系列。玩家:
[{
"_id": {
"$oid": "6009cf73445ff54178c9f123"
},
"Nb_Player": 10,
"Name_Player": "Roddick",
"Nationality": "United States",
"Score": 7,
"Name_Tournament": "Roland Garros",
"Gender": "Male"
},{
"_id": {
"$oid": "6009cf73445ff54178c9f124"
},
"Nb_Player": 10,
"Name_Player": "Roddick",
"Nationality": "United States",
"Score": 8,
"Name_Tournament": "Australia Open",
"Gender": "Male"
},{
"_id": {
"$oid": "6009cf73445ff54178c9f125"
},
"Nb_Player": 10,
"Name_Player": "Roddick",
"Nationality": "United States",
"Score": 8,
"Name_Tournament": "Flusshing Meadows",
"Gender": "Male"
},{
"_id": {
"$oid": "6009cf73445ff54178c9f126"
},
"Nb_Player": 10,
"Name_Player": "Roddick",
"Nationality": "United States",
"Score": 0,
"Name_Tournament": "Paris-Bercy Open",
"Gender": "Male"
},{
"_id": {
"$oid": "6009cf73445ff54178c9f127"
},
"Nb_Player": 20,
"Name_Player": "Ginepri",
"Nationality": "United States",
"Score": 8,
"Name_Tournament": "Roland Garros",
"Gender": "Male"
},{
"_id": {
"$oid": "6009cf73445ff54178c9f128"
},
"Nb_Player": 30,
"Name_Player": "Gasquet",
"Nationality": "France",
"Score": 1,
"Name_Tournament": "Australia Open",
"Gender": "Male"
},{
"_id": {
"$oid": "6009cf73445ff54178c9f129"
},
"Nb_Player": 40,
"Name_Player": "Montfils",
"Nationality": "France",
"Score": 3,
"Name_Tournament": "Australia Open",
"Gender": "Male"
},{
"_id": {
"$oid": "6009cf73445ff54178c9f12a"
},
"Nb_Player": 100,
"Name_Player": "Mauresmo",
"Nationality": "France",
"Score": null,
"Name_Tournament": null,
"Gender": "Female"
},{
"_id": {
"$oid": "6009cf73445ff54178c9f12b"
},
"Nb_Player": 200,
"Name_Player": "Davenport",
"Nationality": "United States",
"Score": 4,
"Name_Tournament": "Roland Garros",
"Gender": "Female"
}]
和团队:
[{
"_id": {
"$oid": "6020251048a99f26045bb879"
},
"Nb_Team": 1,
"Name_Player_1": "Roddick",
"Name_Player_2": "Montfils",
"Score": 9,
"Name_Tournament": "Roland Garros"
},{
"_id": {
"$oid": "6020251048a99f26045bb87a"
},
"Nb_Team": 2,
"Name_Player_1": "Ginepri",
"Name_Player_2": "Gasquet",
"Score": 7,
"Name_Tournament": "Roland Garros"
},{
"_id": {
"$oid": "6020251048a99f26045bb87b"
},
"Nb_Team": 1,
"Name_Player_1": "Roddick",
"Name_Player_2": "Montfils",
"Score": 7,
"Name_Tournament": "Flusshing Meadows"
},{
"_id": {
"$oid": "6020251048a99f26045bb87c"
},
"Nb_Team": 2,
"Name_Player_1": "Ginepri",
"Name_Player_2": "Gasquet",
"Score": 8,
"Name_Tournament": "Flusshing Meadows"
}]
作为输出,我希望法国国籍的球员 (Name_Player) 在 Teams 以及他们的 Nb_Team 中比赛。像这样的东西:
{ "_id" : { "Player" : "Montfils", "Nationality" : "France", "Nb_Team": 1 } }
{ "_id" : { "Player" : "Gasquet", "Nationality" : "France", "Nb_Team": 2 } }
我尝试了 3 $lookup:
db.Player.aggregate([
{
"$lookup": {
"from": "Teams",
"localField": "Name_Player",
"foreignField": "Name_Player_1",
"as": "FrenchPlayerTeam1"
}
},
{
"$lookup": {
"from": "Teams",
"localField": "Name_Player",
"foreignField": "Name_Player_2",
"as": "FrenchPlayerTeam2"
}
},
{
"$lookup": {
"from": "Teams",
"localField": "Name_Tournament",
"foreignField": "Name_Tournament",
"as": "Name_Tournament"
}
},
{ "$match": {"Nationality": "France", "Score": {"$exists": true,"$ne": null}, "Name_Tournament": {"$exists": true,"$ne": null} }},
{ "$group": {
"_id": {
"Player":"$Name_Player",
"Nationality": "$Nationality",
"Nb_Team": "$Nb_Team"},
}}
]);
结果是:
[ { _id: { Player: 'Gasquet', Nationality: 'France' } },
{ _id: { Player: 'Montfils', Nationality: 'France' } } ]
如果我在第二次 $lookup 之后尝试使用 $unwind,我根本不会得到任何结果。有没有办法得到我想要的结果?谢谢
解决方案
不确定我是否正确理解了您的要求,但从您的示例数据看来,两个玩家都将拥有Nb_Team:2
.
不过,这里有一个Mongo Playground的查询。
db.Player.aggregate([
{
"$match": {
"Nationality": "France",
"Score": {
"$exists": true,
"$ne": null
}
}
},
{
"$lookup": {
"from": "Teams",
"let": {
name: "$Name_Player"
},
"pipeline": [
{
$match: {
$expr: {
$or: [
{
$eq: [
"$Name_Player_1",
"$$name"
]
},
{
$eq: [
"$Name_Player_2",
"$$name"
]
}
]
}
}
},
{
"$count": "cnt"
}
],
"as": "Nb_Team"
}
},
{
"$unwind": "$Nb_Team"
},
{
$project: {
"_id": {
"Player": "$Name_Player",
"Nationality": "$Nationality",
"Nb_Team": "$Nb_Team.cnt"
}
}
}
])
这个想法是使用$lookup 子管道来操纵$lookup
结果。您可以轻松地修改$lookup
子管道中的查询并$project
使其适合您的需求。
推荐阅读
- php - 计数订单 Laravel
- python - 如何区分较高的数字和较低的数字
- r - 对称矩阵的名称(包矩阵)
- android - 泛型函数签名中 where 关键字的用途是什么?
- javascript - 当多个视频在一页中时,在模式关闭时停止 vimeo 视频
- firefox - TortoiseSVN 将类拖放到 Firefox 中的 textarea 的问题
- linux - grep 一个“文本”并打印文本前后的所有行。每个日志会话由 2 个空行分隔
- asp.net - 用户从支付网关发回后,Asp.net 会话被重置
- php - 使用 Centos7 服务器连接到我的电子邮件时出现问题
- r - 如何从我的时间序列数据中排除一个月?