如何在Mongoose中将Lookup管道的投影值查询为键值对
问题描述
当前使用Mongoose执行如下$lookup聚合查询:
{ $lookup:{ from:'response', localField:'_id', foreignField:'user', as:'dataResponse', pipeline:[{$project:{ resId:1, status:1 }}] } }
查询返回结果示例:
{ email: "test@test.com", dataResponse: [ {_id: '63515eea05c8c884a33b291d', resId: '632f2d8e470895396dccefdb', status: 'IN_PROGRESS'}, {_id: '6385ee9f451fa8879071bcde', resId: '63771adafa3b611596aaa15d', status: 'CREATED'} ] }
需要将dataResponse字段从数组格式转换为以resId为键、status为值的键值对对象,最终期望结果如下:
{ email: "test@test.com", dataResponse: { "632f2d8e470895396dccefdb": 'IN_PROGRESS', "63771adafa3b611596aaa15d": 'CREATED' } }
实现方案
在原聚合管道的$lookup阶段之后,添加一个$set阶段,通过$map和$arrayToObject操作完成格式转换:
完整聚合管道
[ { $lookup:{ from:'response', localField:'_id', foreignField:'user', as:'dataResponse', pipeline:[{$project:{ resId:1, status:1 }}] } }, { $set: { dataResponse: { $arrayToObject: { $map: { input: "$dataResponse", as: "item", in: { k: "$$item.resId", v: "$$item.status" } } } } } } ]
步骤说明
$map遍历数组:将dataResponse数组中的每个元素转换为包含k(键)和v(值)的对象,其中k对应元素的resId,v对应元素的status$arrayToObject转换为对象:把$map生成的数组直接转换成键值对格式的对象$set替换字段:用转换后的对象覆盖原来的dataResponse字段
处理空数组场景(可选)
如果需要兼容dataResponse为空数组的情况,可通过$cond判断返回空对象:
{ $set: { dataResponse: { $cond: { if: { $eq: ["$dataResponse", []] }, then: {}, else: { $arrayToObject: { $map: { input: "$dataResponse", as: "item", in: { k: "$$item.resId", v: "$$item.status" } } } } } } } }
内容的提问来源于stack exchange,提问作者dextey
相关产品推荐
相关产品推荐

