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

基于键名使用MongoDB $lookup关联tables与table_rows集合

使用MongoDB $lookup关联tables与table_rows集合

我们有两个MongoDB集合tables和table_rows,结构分别如下:

集合结构

tables集合示例文档

{
  "_id": "641ce65852a7ccd2f4a7b298",
  "name": "table name",
  "description": "table description",
  "columns": [{
    "_id": "641ce65852a7ccd2f4a7b299",
    "name": "column 1",
    "dataType": "String"
  }, {
    "_id": "641cf95543a5f258bfaf69e3",
    "name": "column 2",
    "dataType": "Number"
  }]
}

table_rows集合示例文档

{
  "tableId": "641ce65852a7ccd2f4a7b298",
  "641ce65852a7ccd2f4a7b299": "Example string",
  "641cf95543a5f258bfaf69e3": 101
}

这两个集合对应常规表格数据(2列1行),现在需要通过$lookup,基于tables.columns._id和table_rows的键名关联,把列定义(名称、数据类型)和单元格值结合起来。

解决方案

直接用$lookup无法直接匹配动态键名,需先将table_rows的键值对转换为数组,再与tables的列关联。以下是从table_rows集合发起的聚合实现:

聚合步骤说明

  • 筛选目标行:用$match过滤指定tableId的行(可选,按需添加)
  • 转换行数据为数组:用$objectToArray将table_rows中除tableId外的键值对转为{k: 列_id, v: 单元格值}格式的数组
  • 关联表格元数据:用$lookup关联tables集合,匹配tableId与tables._id
  • 展开关联结果:用$unwind展开tables的关联数组结果
  • 关联列定义与值:通过嵌套$lookup将行数据数组与tables.columns关联,匹配k与columns._id并提取对应值
  • 整理输出结构:用$project和$map整合关联后的列定义与值,得到清晰的结果结构

完整聚合代码

db.table_rows.aggregate([
  // 可选:筛选特定表格的行
  { $match: { tableId: "641ce65852a7ccd2f4a7b298" } },
  // 将行数据(除tableId外)转为数组
  {
    $addFields: {
      rowData: {
        $filter: {
          input: { $objectToArray: "$$ROOT" },
          cond: { $ne: ["$$this.k", "tableId"] }
        }
      }
    }
  },
  // 关联tables集合获取列定义
  {
    $lookup: {
      from: "tables",
      localField: "tableId",
      foreignField: "_id",
      as: "tableInfo"
    }
  },
  { $unwind: "$tableInfo" },
  // 把行数据和列定义关联
  {
    $lookup: {
      from: "tables",
      let: { rowCols: "$rowData" },
      pipeline: [
        { $match: { $expr: { $eq: ["$_id", "$$CURRENT.tableId"] } } },
        { $unwind: "$columns" },
        {
          $match: {
            $expr: {
              $in: ["$columns._id", "$$rowCols.k"]
            }
          }
        },
        {
          $addFields: {
            value: {
              $arrayElemAt: [
                {
                  $filter: {
                    input: "$$rowCols",
                    cond: { $eq: ["$$this.k", "$columns._id"] }
                  }
                },
                0
              ].v
            }
          }
        },
        { $project: { columns: 1, value: 1, _id: 0 } }
      ],
      as: "columnsWithValues"
    }
  },
  // 整理最终输出结构
  {
    $project: {
      tableId: 1,
      tableName: "$tableInfo.name",
      columns: {
        $map: {
          input: "$columnsWithValues",
          as: "col",
          in: {
            columnId: "$$col.columns._id",
            columnName: "$$col.columns.name",
            dataType: "$$col.columns.dataType",
            value: "$$col.value"
          }
        }
      },
      rowData: 0,
      tableInfo: 0
    }
  }
])

输出结果示例

{
  "_id": ObjectId("..."),
  "tableId": "641ce65852a7ccd2f4a7b298",
  "tableName": "table name",
  "columns": [
    {
      "columnId": "641ce65852a7ccd2f4a7b299",
      "columnName": "column 1",
      "dataType": "String",
      "value": "Example string"
    },
    {
      "columnId": "641cf95543a5f258bfaf69e3",
      "columnName": "column 2",
      "dataType": "Number",
      "value": 101
    }
  ]
}

若从tables集合发起聚合,逻辑类似:先展开columns数组,再关联table_rows并提取对应键的值即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 05:55:06