创建Mongo视图时如何对关联添加的数组数据按条件过滤
解决方案
你当前的问题是直接将全量关联到的hero_foods数据赋值给了所有food_groups元素,没有做分类过滤。你只需要将原语句中的$set阶段替换为带过滤逻辑的数组遍历逻辑即可,修改后的视图创建语句如下:
database.createView("recommendation_items_view", recommendation_items, Arrays.asList( // 原有过滤逻辑保留 new Document("$match", new Document("type", "DIET")), // 原有关联逻辑保留,先把匹配的所有hero_foods查出来 new Document("$lookup", new Document("from", "hero_foods") .append("localField", "_id") .append("foreignField", "recommendations_group") .append("as", "recommendation_items.hero_foods_list")), // 替换原有$set阶段:遍历food_groups做分类过滤 new Document("$set", new Document("recommendation_items.food_groups", // 用$map遍历food_groups数组的每个元素 new Document("$map", new Document("input", "$recommendation_items.food_groups") .append("as", "group") .append("in", // 合并原有group字段,新增过滤后的hero_foods_list new Document("$mergeObjects", Arrays.asList( "$$group", new Document("hero_foods_list", // 过滤出food_group和当前group的category_id相等的记录 new Document("$filter", new Document("input", "$recommendation_items.hero_foods_list") .append("as", "food") .append("cond", new Document("$eq", Arrays.asList("$$food.food_group", "$$group.category_id"))) ) ) )) ) ) ) ), // 原有project逻辑保留,删除临时存储的全量hero_foods_list new Document("$project", new Document("recommendation_items.hero_foods_list", 0L)) ) );
逻辑说明
- 保留原有
$match、$lookup逻辑,先把关联到当前推荐项的所有英雄食物数据查出来,存在临时字段recommendation_items.hero_foods_list中 - 新增的
$set阶段通过$map遍历每个食物分组,再通过$filter筛选出和当前分组category_id匹配的英雄食物,赋值给该分组的hero_foods_list字段 - 最后通过
$project删除临时存储的全量英雄食物字段,得到最终结构
内容的提问来源于stack exchange,提问作者Sanjay Naik
相关产品推荐
相关产品推荐

