MongoDB聚合查询:根据type值映射返回对应code字段
解决方案:在MongoDB聚合管道中映射type到对应code值
针对你的需求——根据集合中存储的type值(对应objList里的定义)返回对应的code,比如type=2时返回BN,我给你两种实用的实现方案:
方案一:硬编码映射(适合固定不变的常量)
直接在聚合管道中加入$addFields阶段,用$switch操作符匹配type值返回对应code,修改后的聚合管道如下:
// 现有常量定义 var objList= { BMW: { type: 1, code: 'BW' }, BENZ: { type: 2, code: 'BN' }, RR: { type: 3, code: 'RR' }, }; // 修改后的聚合管道 var aggregateList = [ { $match : matches }, { $unwind : unwind }, { $group : group1 }, { $unwind : unwind }, // 新增:映射type到code的阶段 { $addFields: { code: { $switch: { branches: [ { case: { $eq: ["$type", 1] }, then: 'BW' }, { case: { $eq: ["$type", 2] }, then: 'BN' }, { case: { $eq: ["$type", 3] }, then: 'RR' } ], default: null // 处理未定义的type值,可按需修改 } } } }, { $sort : sort }, { $skip : skip }, { $limit : limit }, ]; var db_collections = Car.aggregate(aggregateList);
说明:
$addFields会给每个聚合文档新增一个code字段,不会影响原有字段的保留$switch的分支完全对应你objList里的映射关系,逻辑清晰直观default可以设置你需要的默认值,比如空字符串或者特定标识
方案二:动态映射(适合常量可能变动的场景)
如果你的objList后续可能会更新,不想每次都修改聚合管道的硬编码,可以先把常量转化为数组,再用数组匹配的方式实现映射:
// 现有常量定义 var objList= { BMW: { type: 1, code: 'BW' }, BENZ: { type: 2, code: 'BN' }, RR: { type: 3, code: 'RR' }, }; // 将常量转化为聚合可用的数组映射 var typeCodeMap = Object.values(objList).map(item => ({type: item.type, code: item.code})); // 修改后的聚合管道 var aggregateList = [ { $match : matches }, { $unwind : unwind }, { $group : group1 }, { $unwind : unwind }, // 新增:动态映射type到code的阶段 { $addFields: { code: { $let: { vars: { matchedItem: { $arrayElemAt: [ typeCodeMap, { $indexOfArray: [typeCodeMap.map(item => item.type), "$type"] } ] } }, in: "$$matchedItem.code" } } } }, { $sort : sort }, { $skip : skip }, { $limit : limit }, ]; var db_collections = Car.aggregate(aggregateList);
说明:
- 只需要维护
objList这个常量,聚合管道的逻辑不需要改动 - 通过
$arrayElemAt和$indexOfArray找到匹配的映射项,再提取code值 - 同样支持默认值处理,如果
type不存在于映射中,$$matchedItem会是null,你可以用$ifNull设置默认值
不管用哪种方案,当你的过滤条件指定type=2时,聚合结果里都会自动带上对应的code=BN,完全满足你的需求。
内容的提问来源于stack exchange,提问作者Prabhakaran
相关产品推荐
相关产品推荐

