如何用MongoDB单查询实现指定餐厅的菜品去重匹配?
MongoDB实现指定餐厅菜品去重查询
可以直接用MongoDB的聚合框架或者分步查询实现你的需求,以下是两种可行方案:
方案一:单聚合管道完成(推荐)
通过分组判断菜品归属,直接筛选出符合要求的记录:
db.Resturant.aggregate([ // 第一步:筛选目标餐厅的所有记录 { "$match": { "name": {"$in": ["resturant1", "resturant2"]} } }, // 第二步:按菜品分组,收集对应餐厅的所有原始文档 { "$group": { "_id": "$food", "docs": {"$push": "$$ROOT"}, "restaurants": {"$addToSet": "$name"} } }, // 第三步:判断并选择保留的文档 { "$project": { "selectedDoc": { "$cond": [ {"$in": ["resturant1", "$restaurants"]}, {"$arrayElemAt": [{"$filter": {"input": "$docs", "cond": {"$eq": ["$$this.name", "resturant1"]}}}, 0]}, {"$arrayElemAt": [{"$filter": {"input": "$docs", "cond": {"$eq": ["$$this.name", "resturant2"]}}}, 0]} ] } } }, // 第四步:恢复原始文档结构 { "$replaceRoot": {"newRoot": "$selectedDoc"} } ])
逻辑说明:
- 先过滤出
resturant1和resturant2的所有记录,减少后续处理数据量 - 按菜品分组,标记每个菜品涉及的餐厅列表
- 对每个菜品分组:如果
resturant1有该菜品,就保留resturant1的记录;否则保留resturant2的记录 - 最后把选中的文档恢复成原始结构,得到你需要的2条结果
方案二:分步查询+组合条件
先获取resturant1的菜品列表,再组合查询条件过滤:
// 第一步:获取resturant1的所有菜品 const rest1Foods = db.Resturant.find({"name": "resturant1"}, {"food": 1, "_id": 0}).map(doc => doc.food); // 第二步:查询符合条件的记录 db.Resturant.find({ "$or": [ {"name": "resturant1"}, {"name": "resturant2", "food": {"$nin": rest1Foods}} ] })
逻辑说明:
- 先查询得到
resturant1的所有菜品 - 再通过
$or组合两个条件:要么是resturant1的记录,要么是resturant2中不在resturant1菜品列表里的记录
两种方案都能直接返回你预期的结果,不需要额外的代码处理。
内容的提问来源于stack exchange,提问作者DeveloperJoe
相关产品推荐
相关产品推荐

