如何编写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 } } ])
代码逻辑拆解:
- $lookup:通过
form里的type字段关联type集合,把匹配到的类型配置存入typeDetails数组。 - $unwind:因为每个表单只对应一种类型,所以把数组拆成单个对象,方便后续遍历处理。
- $addFields + $map:遍历表单的
values数组,对每个字段做判断:- 先从关联到的类型配置里筛选出当前字段的属性详情;
- 如果属性是SELECT类型,就从它的选项列表里匹配对应key的label对象,替换原value;非SELECT类型直接保留原始值。
- $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
相关产品推荐
相关产品推荐

