如何使用pipeline lookup查询数组类型service_id对应的各服务关联数据
解决方案
你只需要调整匹配逻辑,同时适配数组类型的service_id的特性即可,核心改动有两处:
- 将原来的等值匹配
$eq改为数组包含匹配$in,适配数组类型的service_id - 新增映射阶段保留原
service_id数组的重复项和顺序,避免MongoDB lookup默认去重导致结果和预期不一致
完整调整后代码
Bookings.aggregate([ { "$match": { "customer_id": new mongoose.Types.ObjectId(req.body.user_id) } }, { $lookup: { from: "users", localField: "saloon_user_id", foreignField: "_id", as: "userRole" } }, { $lookup: { from: "owner_servicedatas", let: { // 若service_id数组存的是字符串格式ID,打开下面这行转成ObjectId再匹配 // id: {$map: {input: "$service_id", in: {$toObjectId: "$$this"}}} id: "$service_id" }, pipeline: [ { $match: { $expr: { // 核心改动:将eq改为in,匹配所有_id在service_id数组内的服务文档 $in: ["$_id", "$$id"] } } }, { $lookup: { from: "owner_staffdatas", let: { "portId": "$staff_id" }, pipeline: [ { $match: {$expr:{$eq:["$$portId","$_id" ] } }} ], "as": "staff" } } ], as: "saloon_services_temp" } }, // 按原service_id数组的顺序和重复情况映射结果,和你给出的示例输出完全对齐 { $addFields: { saloon_services: { $map: { input: "$service_id", as: "sid", in: { $first: { $filter: { input: "$saloon_services_temp", cond: { $eq: [ // 若service_id是字符串格式,这里把$$this._id转成字符串即可:$toString: "$$this._id" "$$sid", "$$this._id" ] } } } } } } } }, // 清理临时字段 { $unset: "saloon_services_temp" } ])
注意事项
如果不需要保留service_id的重复项,仅需要返回去重后的关联服务,可以直接删除$addFields和$unset两个阶段,把上面lookup的as字段直接设置为saloon_services即可。
内容的提问来源于stack exchange,提问作者Amit Sharma
相关产品推荐
相关产品推荐

