【问题标题】:Select from collection a on clause from JOIN on collection b从集合 b 的 JOIN 中选择集合 a on 子句
【发布时间】:2019-04-17 17:04:48
【问题描述】:

我有两个集合:gamesquestions
game 架构:

{ 
  _id: ObjectId, 
  status: 'played',
  questions: 
     [ 
       { questionId: ObjectId(questions._id) } // ref to questions collection by _id field
     ] 
 }

questions 架构:

{
  _id: ObjectId(),
  text: foobar
}

游戏可能有两种状态:“活跃”和“已玩”。
我的目标是获取与状态为“已玩”的游戏相关的所有“已玩”问题、方法、问题。

我已尝试对 games 集合进行查询,尝试对 questions 进行查询,但均无效。

其中一些是:

db.games.aggregate([
     {$match: {status: {$ne: 'played'}}}, 
     {
         $lookup: 
           {
            from: 'questions', 
            localField: 'questions.questionId', 
            foreignField: '_id', 
            as: 'game_questions'
         }
      }, 
    {$project: {game_questions: 1}}, 
    {$unwind: {path: '$game_questions', preserveNullAndEmptyArrays: false}}
   ])

或者

db.questions.aggregate([
     { $project: {text: 1}}, 
     { $lookup: {
        from: 'games', 
        pipeline: [
           { $match: {status:'played' }}, 
           { $project: { status: 1 }}
        ], 
        as: 'game_data' 
      }}
])

底线: 在提出请求后,我想获得一个包含问题的列表,其中游戏状态为“已玩”。

【问题讨论】:

    标签: mongodb mongoose mongodb-query aggregation-framework


    【解决方案1】:

    您可以将$unwind$replaceRoot$lookup 阶段中​​找到的数据一起使用

    db.games.aggregate([
      { "$match": { "status": "played" }},
      { "$lookup": {
        "from": "questions",
        "let": { "questions": "$questions.questionId" },
        "pipeline": [
          { "$match": { "$expr": { "$in": ["$_id", "$$questions"] }}}
        ],
        "as": "game_data"
      }},
      { "$unwind": "$game_data" },
      { "$replaceRoot": { "newRoot": "$game_data" }}
    ])
    

    或者

    db.games.aggregate([
      { "$match": { "status": "played" }}, 
      { "$lookup": {    
        "from": "questions", 
        "localField": "questions.questionId", 
        "foreignField": "_id", 
        "as": "game_data"
      }}, 
      { "$unwind": "$game_data" },
      { "$replaceRoot": { "newRoot": "$game_data" }}
    ])
    

    【讨论】:

    • 使用第一个 $lookup 而不是第二个的任何特殊原因?
    • @Murilo $lookup 语法与pipeline 是旧$lookup 的高级版本。它允许您加入多个条件,并且可以允许您使用所有聚合运算符。而且我确实比旧的更喜欢。
    • 好的。谢谢你:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-03
    • 1970-01-01
    • 2016-05-01
    • 1970-01-01
    相关资源
    最近更新 更多