所以我有一个集合users
,该集合中的每个文档以及其他属性在另一个集合workouts
中都有一个文档ID数组。
集合workouts
中的每个文档都有一个名为date
的属性。
这就是我想要得到的:
对于特定用户,我想获取属于该用户的锻炼的{workoutId,trainingDate}数组,按日期排序。
这是我的尝试,效果很好。
Users.aggregate([
{
$match : {
_id : ObjectId("whateverTheUserIdIs")
}
},
{
$unwind : {
path : "$workouts"
}
}, {
$lookup : {
from : "workouts",
localField : "workouts",
foreignField : "_id",
as : "workoutDocumentsArray"
}
}, {
$project : {
_id : false,
workoutData : {
$arrayElemAt : [
$workoutDocumentsArray,
0
]
}
}
}, {
$project : {
date : "$workoutData.date",
id : "$workoutData._id"
}
}, {
$sort : {date : -1}
}
])
但是我拒绝相信我需要所有这些,因为在SQL中如此简单的查询!!我相信我至少必须能够将两个$project
阶段合并为一个阶段?但是我无法弄清楚如何看文档。
提前感谢您抽出宝贵的时间! ;)
==== 编辑-这是一些示例数据
收藏用户:
[{
_id:xxx,
workouts: [2,4,6]
},{
_id: yyy,
workouts: [1,3,5]
}]
大学体育锻炼:
[{
_id:1,
date: 1/1/1901
},{
_id:2,
date: 2/2/1902
},{
_id:3,
date: 3/3/1903
},{
_id:4,
date: 4/4/1904
},{
_id:5,
date: 5/5/1905
},{
_id:6,
date: 6/6/1906
}]
在运行查询(例如用户xxx)后,我只想获得属于他的锻炼(其ID出现在他的锻炼数组中),所以我想要的结果如下所示:
[{
id:6,
date: 6/6/1906
},{
id:4,
date: 4/4/1904
},{
id:2,
date: 2/2/1902
}]
答案 0 :(得分:1)
您无需$unwind
个workouts
数组,因为它已经包含_id
个数组,并且可以使用$replaceRoot
而不是$project
>
Users.aggregate([
{ "$match": { "_id" : ObjectId("whateverTheUserIdIs") }},
{ "$lookup": {
"from" : "workouts",
"localField" : "workouts",
"foreignField" : "_id",
"as" : "workoutDocumentsArray"
}},
{ "$unwind": "$workoutDocumentsArray" },
{ "$replaceRoot": { "newRoot": "$workoutDocumentsArray" }}
{ "$sort" : { "date" : -1 }}
])
甚至使用新的$lookup
语法
Users.aggregate([
{ "$match" : { "_id": ObjectId("whateverTheUserIdIs") }},
{ "$lookup" : {
"from" : "workouts",
"let": { "workouts": "$workouts" },
"pipeline": [
{ "$match": { "$expr": { "$in": ["$_id", "$$workouts"] }}},
{ "$sort" : { "date" : -1 }}
]
"as" : "workoutDocumentsArray"
}},
{ "$unwind": "$workoutDocumentsArray" },
{ "$replaceRoot": { "newRoot": "$workoutDocumentsArray" }}
])