查询数据库时如何按parentID去重,避免返回重复的菜谱数据?
方案1:不修改现有数据结构,直接用聚合查询实现去重
这是最快实现需求的方式,无需调整存储结构,仅修改查询逻辑即可,以MongoDB为例,查询逻辑如下:
- 先执行
$match阶段过滤符合搜索要求的文档(比如关键词匹配、热量大于400),提前缩小数据范围 - 再用
$group阶段按parentId分组,每组仅保留1条文档,你可以根据需求选择保留每组的第一条、热量最高的或者其他规则的条目 - 最后用
$replaceRoot把分组后的文档还原为原始结构
示例代码:
db.recipes.aggregate([ // 匹配你的搜索条件 { $match: { name: /Jerk chicken/i, calories: { $gt: 400 } } }, // 按parentId分组,每组取第一条数据 { $group: { _id: "$parentId", recipeItem: { $first: "$$ROOT" } } }, // 还原文档原始结构 { $replaceRoot: { newRoot: "$recipeItem" } } ])
如果是用关系型数据库(比如PostgreSQL),可以用DISTINCT ON (parent_id)或者窗口函数ROW_NUMBER() OVER (PARTITION BY parent_id ORDER BY calories DESC),筛选行号为1的条目即可,逻辑完全一致。
这个方案的优势是改造成本极低,适合快速上线,注意给parentId和常用的筛选字段加联合索引,可以大幅提升聚合查询的性能。
方案2:拆分集合存储基础菜谱和变体
你提到的新增原始菜谱集合、变体存为子集合的方案完全可行,是中长期更合理的架构选择:
- 新增
base_recipes集合存储所有菜谱的公共信息:比如通用名称、基础做法、公共食材等,每条文档的_id对应原来的parentId - 原有
recipes集合调整为recipe_variants,仅存储变体的差异化内容:比如分量、调整后的热量、专属调整项,关联base_recipes的_id - 搜索列表直接查询
base_recipes集合即可,用户点击进入菜谱详情页时,再查询关联的所有变体数据返回
这个方案的优势是数据结构更清晰,查询性能更高,后续如果要做变体的单独统计、定向筛选等功能,扩展性更好;唯一的成本是需要做现有数据的迁移,同步调整现有读写逻辑,适合中长期的架构迭代。
内容的提问来源于stack exchange,提问作者Lukas Vis
相关产品推荐
相关产品推荐

