MongoDB聚合查询:嵌套属性关联Lookup分组实现求助
MongoDB 聚合查询:按 ship_to、sold_to 和 contact_email 分组并验证关联
下面是整合了关联查询、ref匹配校验及邮箱验证的完整聚合管道,直接可用:
db.orders.aggregate([ // 关联locations集合,获取ship_to对应的reference_id { $lookup: { from: "locations", localField: "ship_to_id", foreignField: "_id", as: "ship_to_location" } }, // 关联locations集合,获取sold_to对应的reference_id { $lookup: { from: "locations", localField: "sold_to_id", foreignField: "_id", as: "sold_to_location" } }, // 展开关联结果(每个订单对应唯一位置文档,直接展开即可) { $unwind: "$ship_to_location" }, { $unwind: "$sold_to_location" }, // 执行验证:ref匹配+邮箱有效性检查 { $match: { $expr: { $and: [ // 匹配ship_to的reference_id与contact_details中的ship_to_ref { $eq: ["$ship_to_location.reference_id", "$contact_details.ship_to_ref"] }, // 匹配sold_to的reference_id与contact_details中的sold_to_ref { $eq: ["$sold_to_location.reference_id", "$contact_details.sold_to_ref"] }, // 确保contact_email存在 { $exists: ["$contact_email", true] }, // 可选:校验邮箱格式,可根据业务调整正则 { $regexMatch: { input: "$contact_email", regex: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/ } } ] } } }, // 按指定字段分组 { $group: { _id: { ship_to_ref: "$ship_to_location.reference_id", sold_to_ref: "$sold_to_location.reference_id", contact_email: "$contact_email" }, // 统计每组订单数量 order_count: { $sum: 1 }, // 收集该组下的所有订单ID(也可以换成$$ROOT保留完整订单) order_ids: { $push: "$_id" } } }, // 可选:格式化输出,让结果更清晰 { $project: { _id: 0, ship_to_ref: "$_id.ship_to_ref", sold_to_ref: "$_id.sold_to_ref", contact_email: "$_id.contact_email", order_count: 1, order_ids: 1 } } ])
关键阶段说明
- 两次$lookup:分别通过订单的
ship_to_id和sold_to_id关联locations集合,拿到对应的reference_id。 - $unwind:把lookup返回的数组转成单个文档,方便后续字段匹配(如果订单的位置ID可能对应多个位置文档,可添加
preserveNullAndEmptyArrays: false过滤无匹配的订单)。 - $match:完成核心校验逻辑,既确保关联回来的reference_id和订单自带的ref一致,又保证contact_email存在且格式合法。
- $group:按
ship_to_ref、sold_to_ref和contact_email三个维度分组,同时统计订单数量、收集订单ID。
可调整项
- 如果不需要邮箱格式校验,直接删掉
$regexMatch那一行即可。 - 若需要保留完整订单信息,把
$group里的order_ids换成orders: { $push: "$$ROOT" }。
内容的提问来源于stack exchange,提问作者Amaarockz
相关产品推荐
相关产品推荐

