You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 00:15:32