如何使用MongoDB的$lookup和$addFields匹配字段返回对应distance值
可行的MongoDB聚合实现方案
你可以直接套用以下代码,适配你提前定义的JS起始地址变量即可(以下为Node.js驱动写法,其他语言写法逻辑一致):
// 提前定义的固定起始地址变量 const start_province = "Rome"; const start_city = "Rome"; const result = await db.collection("Users").aggregate([ // 第一步:筛选可用用户,提前过滤无效数据提升性能 { $match: { available: true } }, // 第二步:关联Distances集合匹配对应距离 { $lookup: { from: "Distances", let: { user_province: "$province", user_city: "$city" }, pipeline: [ { $match: { $expr: { $and: [ // 匹配固定起始地址 { $eq: ["$start_province", start_province] }, { $eq: ["$start_city", start_city] }, // 匹配用户地址作为终点 { $eq: ["$end_province", "$$user_province"] }, { $eq: ["$end_city", "$$user_city"] } ] } } }, // 仅返回需要的distance字段,减少冗余数据 { $project: { distance: 1, _id: 0 } } ], as: "matched_distance" } }, // 第三步:提取距离值,无匹配时默认设为0 { $addFields: { distance: { $ifNull: [ { $first: "$matched_distance.distance" }, 0 ] } } }, // 可选:移除多余的中间匹配字段 { $project: { matched_distance: 0 } } ]).toArray();
如果你使用的MongoDB版本低于4.4不支持$first操作符,可以把第三步$addFields的逻辑替换为:
{ $addFields: { distance: { $ifNull: [ { $arrayElemAt: [ "$matched_distance.distance", 0 ] }, 0 ] } } }
该方案在你提供的示例数据下执行,输出结果和你给出的预期完全一致。
内容的提问来源于stack exchange,提问作者lytonist
相关产品推荐
相关产品推荐

