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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 04:08:19