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

如何编写MongoDB查询:关联表单与类型集合并转换SELECT字段值

解决方法:MongoDB聚合查询实现关联替换

看你的场景,是要关联type和form两个集合,查询form时自动把SELECT类型属性的value替换成对应的key-label对象对吧?用MongoDB的聚合框架就能完美搞定,具体的聚合管道代码如下:

db.form.aggregate([
  // 第一步:关联type集合,拉取对应属性配置
  {
    $lookup: {
      from: "type",
      localField: "type",
      foreignField: "id",
      as: "typeDetails"
    }
  },
  // 把关联到的type数组转成单个对象(每个form只对应一个type)
  {
    $unwind: "$typeDetails"
  },
  // 第二步:遍历values数组,替换SELECT类型的value
  {
    $addFields: {
      values: {
        $map: {
          input: "$values",
          as: "val",
          in: {
            $let: {
              vars: {
                // 找到当前value对应的属性详情
                attrInfo: {
                  $first: {
                    $filter: {
                      input: "$typeDetails.attributes",
                      cond: { $eq: ["$$this.id", "$$val.attribute"] }
                    }
                  }
                }
              },
              in: {
                attribute: "$$val.attribute",
                value: {
                  $cond: {
                    // 判断属性类型是否为SELECT
                    if: { $eq: ["$$attrInfo.type", "SELECT"] },
                    // 是SELECT的话,匹配对应的key-label对象
                    then: {
                      $first: {
                        $filter: {
                          input: "$$attrInfo.option",
                          cond: { $eq: ["$$this.key", "$$val.value"] }
                        }
                      }
                    },
                    // 非SELECT类型直接保留原value
                    else: "$$val.value"
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  // 移除临时字段,让结果格式更干净
  {
    $project: {
      typeDetails: 0
    }
  }
])

代码逻辑拆解:

  1. $lookup:通过form里的type字段关联type集合,把匹配到的类型配置存入typeDetails数组。
  2. $unwind:因为每个表单只对应一种类型,所以把数组拆成单个对象,方便后续遍历处理。
  3. $addFields + $map:遍历表单的values数组,对每个字段做判断:
    • 先从关联到的类型配置里筛选出当前字段的属性详情;
    • 如果属性是SELECT类型,就从它的选项列表里匹配对应key的label对象,替换原value;非SELECT类型直接保留原始值。
  4. $project:移除临时的typeDetails字段,让输出结果和你期望的格式完全一致。

用你给出的示例数据测试这个查询,就能得到你想要的结果:

{
  "id": "f-1",
  "type": "t-123",
  "values": [
    { "attribute": "a-1", "value": "my random string" },
    { "attribute": "a-2", "value": { "key": "DE", "label": "Germany" } }
  ]
}

如果用的是其他数据库(比如SQL)或者ORM框架,核心思路也是一样的:先关联获取类型配置,再根据属性类型对值做转换替换。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:31:09