Spring集成MongoDB实现嵌套对象不区分大小写查询问题
解决方案:查询包含所有指定食材(不区分大小写)的菜谱
问题根源
你之前的@Query写法存在逻辑错误:{$all: [{$regex: ?0, $options: 'i'}]}会把传入的整个List<String>当作单个字符串进行正则匹配,而非逐个处理每个食材名称,导致查询逻辑完全不符合预期。
方案1:使用@Query结合SpEL动态生成查询条件
通过Spring表达式(SpEL)遍历食材名称列表,为每个名称生成独立的不区分大小写正则匹配条件,再用$and组合确保所有条件同时满足:
@Repository public interface RecipeRepository extends MongoRepository<Recipe, String> { @Query("{$and: [?#{#ingredientNames.stream().map(name -> {'ingredients.name': {$regex: name, $options: 'i'}}).collect(java.util.stream.Collectors.toList())]}") List<Recipe> findByIngredientsNames(List<String> ingredientNames); }
方案2:使用MongoTemplate实现灵活查询
如果SpEL写法过于复杂,也可以直接用MongoTemplate手动构建查询条件,可读性更强:
@Service public class RecipeService { @Autowired private MongoTemplate mongoTemplate; public List<Recipe> findRecipesByIngredients(List<String> ingredientNames) { Criteria criteria = new Criteria(); // 为每个食材名称添加不区分大小写的正则匹配条件 for (String name : ingredientNames) { criteria.and("ingredients.name").regex(name, "i"); } Query query = new Query(criteria); return mongoTemplate.find(query, Recipe.class); } }
验证逻辑说明
两种方案最终都会生成类似以下的MongoDB原生查询(以查询example1和example2为例):
{ "$and": [ {"ingredients.name": {"$regex": "example1", "$options": "i"}}, {"ingredients.name": {"$regex": "example2", "$options": "i"}} ] }
该查询会返回同时包含名称匹配example1(不区分大小写)和example2(不区分大小写)的食材的所有菜谱,完全符合你的需求。
内容的提问来源于stack exchange,提问作者fnymmm
相关产品推荐
相关产品推荐

