【问题标题】:Lookup and sort the foreign collection查找和排序外国集合
【发布时间】:2019-03-14 05:07:39
【问题描述】:

所以我有一个集合users,并且该集合中的每个文档以及其他属性都具有另一个集合中文档的 ID 数组:workouts。 集合workouts 中的每个文档都有一个名为date 的属性。

这就是我想要得到的:

对于特定用户,我想为属于该用户的锻炼获取一组 {workoutId,锻炼日期},按日期排序。

这是我的尝试,效果很好。

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]
}]

Colleciton 锻炼:

[{
  _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
 }]

【问题讨论】:

  • 您能否发布一些示例数据,以便更容易解释。
  • @AnthonyWinzlet 会的,给我一点时间
  • @AnthonyWinzlet 刚刚添加了更多信息,希望现在有意义

标签: mongodb optimization mongodb-query nosql aggregation-framework


【解决方案1】:

您不需要 $unwind workouts 数组,因为它已经包含 _ids 数组并使用 $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" }}
])

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-06-14
    • 2022-11-10
    • 1970-01-01
    • 2015-01-24
    • 1970-01-01
    • 2016-05-02
    • 2018-06-15
    • 2015-08-31
    相关资源
    最近更新 更多