You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用单条MongoDB查询从三个集合获取指定格式的数据?

MongoDB Aggregation Query to Join Three Collections and Project Custom Fields

要实现你需要的结果,我们可以用MongoDB的聚合管道,通过多次$lookup关联集合,再通过数组操作匹配问题和对应的答案,最终投影出目标格式的数据。以下是完整的查询语句:

db.FormSubmissions.aggregate([
  // 关联FormAnswers,获取当前提交对应的答案文档
  {
    $lookup: {
      from: "FormAnswers",
      localField: "_id",
      foreignField: "FormSubmissionId",
      as: "submissionAnswers"
    }
  },
  // 展开答案数组(每个提交对应一个答案文档,展开后便于后续处理)
  {
    $unwind: "$submissionAnswers"
  },
  // 关联FormQuestions,获取当前表单版本的问题定义
  {
    $lookup: {
      from: "FormQuestions",
      let: {
        formId: "$FormId",
        formVersionId: "$FormVersionId",
        languageId: "$LanguageId"
      },
      pipeline: [
        {
          $match: {
            $expr: {
              $and: [
                { $eq: ["$FormId", "$$formId"] },
                { $eq: ["$FormVersionId", "$$formVersionId"] },
                { $eq: ["$LanguageId", "$$languageId"] }
              ]
            }
          }
        }
      ],
      as: "formQuestions"
    }
  },
  // 展开问题数组(每个表单版本对应一个问题文档)
  {
    $unwind: "$formQuestions"
  },
  // 投影出需要的字段,匹配问题对应的答案值
  {
    $project: {
      _id: 1,
      LanguageId: 1,
      FormId: 1,
      FormVersionId: 1,
      SubmittedOn: 1,
      EmployeeId: 1,
      // 获取Name对应的答案
      Name: {
        $let: {
          vars: {
            nameQuestion: {
              $arrayElemAt: [
                {
                  $filter: {
                    input: "$formQuestions.Questions",
                    cond: { $eq: ["$$this.Question", "Name"] }
                  }
                },
                0
              ]
            }
          },
          in: {
            $arrayElemAt: [
              {
                $filter: {
                  input: "$submissionAnswers.Answers",
                  cond: { $eq: ["$$this.FormQuestionId", "$$nameQuestion._id"] }
                }
              },
              0
            ].Value
          }
        }
      },
      // 获取Type对应的答案
      Type: {
        $let: {
          vars: {
            typeQuestion: {
              $arrayElemAt: [
                {
                  $filter: {
                    input: "$formQuestions.Questions",
                    cond: { $eq: ["$$this.Question", "Type"] }
                  }
                },
                0
              ]
            }
          },
          in: {
            $arrayElemAt: [
              {
                $filter: {
                  input: "$submissionAnswers.Answers",
                  cond: { $eq: ["$$this.FormQuestionId", "$$typeQuestion._id"] }
                }
              },
              0
            ].Value
          }
        }
      }
    }
  }
])

关键步骤说明:

  1. 第一次$lookup:将FormSubmissions与FormAnswers通过_id和FormSubmissionId关联,拿到当前提交的所有答案。
  2. $unwind:展开答案数组,因为每个提交对应唯一的答案文档,展开后可以直接处理单个答案集合。
  3. 第二次$lookup:通过表单ID、版本ID和语言ID关联FormQuestions,获取该表单版本的所有问题定义,确保我们能匹配到正确的问题名称对应的答案。
  4. $unwind:展开问题文档数组,同样因为每个表单版本对应唯一的问题文档。
  5. $project:使用$filter和$arrayElemAt从问题数组中找到Question为"Name"和"Type"的项,再从答案数组中匹配对应的FormQuestionId,最终提取出答案的Value作为新增字段。

这个查询会返回你需要的格式数据,每个提交记录都包含原有的字段,加上对应的Name和Type值。

内容的提问来源于stack exchange,提问作者Pankaj Kamadiya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 16:32:47