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

Spring Boot MongoDB实现(lang与name/coef组合)多条件模糊分页查询

实现Spring Boot中MongoDB嵌套文档的多条件分页查询

需求背景

现有MongoDB集合结构如下:

module: [
 {
   "id": "b92816df-fcc7-4e0f-9524-f81d0a5097b4", 
   "interventions": [ 
       { 
         "lang": "en-US", 
         "name": "Mathematic",
         "coef": 5 
       }, 
       { 
         "lang": "fr-FR", 
         "name": "Mathematique",
         "coef": 6
       }
   ]
 }
]

需实现查询逻辑:lang精确匹配 且(name模糊匹配 或 coef模糊匹配),同时返回Module类型的分页结果。


实现步骤

1. 定义实体类

创建对应MongoDB文档的Java实体,映射嵌套结构:

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import java.util.List;

@Document(collection = "module")
public class Module {
    @Id
    private String id;
    private List<Intervention> interventions;

    // 构造函数、getter、setter
    public static class Intervention {
        private String lang;
        private String name;
        private Integer coef;

        // 构造函数、getter、setter
    }
}

2. 定义Repository层

继承MongoRepository,提供基础数据操作能力:

import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

public interface ModuleRepository extends MongoRepository<Module, String> {
}

3. 编写Service层查询逻辑

使用MongoTemplate结合Criteria构建复杂查询,同时处理分页:

import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class ModuleService {
    private final MongoTemplate mongoTemplate;

    public ModuleService(MongoTemplate mongoTemplate) {
        this.mongoTemplate = mongoTemplate;
    }

    public Page<Module> searchModules(String lang, String nameKeyword, String coefKeyword, Pageable pageable) {
        // 基础条件:lang精确匹配
        Criteria baseCriteria = Criteria.where("interventions.lang").is(lang);

        // 构建OR条件:name模糊匹配 或 coef模糊匹配
        Criteria orCriteria = new Criteria();
        if (nameKeyword != null && !nameKeyword.isEmpty()) {
            orCriteria.orOperator(
                // name不区分大小写模糊匹配
                Criteria.where("interventions.name").regex(nameKeyword, "i"),
                // coef是数字类型,转字符串后做模糊匹配
                Criteria.where("interventions.coef").regex(String.valueOf(coefKeyword), "i")
            );
        } else if (coefKeyword != null && !coefKeyword.isEmpty()) {
            orCriteria.orOperator(
                Criteria.where("interventions.coef").regex(String.valueOf(coefKeyword), "i")
            );
        }

        // 组合条件:基础条件 AND OR条件
        if (!orCriteria.getCriteria().isEmpty()) {
            baseCriteria.andOperator(orCriteria);
        }

        Query query = Query.query(baseCriteria).with(pageable);

        // 查询分页数据与总条数
        List<Module> moduleList = mongoTemplate.find(query, Module.class);
        long total = mongoTemplate.count(query.skip(0).limit(0), Module.class);

        return new PageImpl<>(moduleList, pageable, total);
    }
}

4. Controller层调用示例

暴露接口供外部调用,接收查询参数与分页参数:

import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ModuleController {
    private final ModuleService moduleService;

    public ModuleController(ModuleService moduleService) {
        this.moduleService = moduleService;
    }

    @GetMapping("/modules/search")
    public Page<Module> searchModules(
            @RequestParam String lang,
            @RequestParam(required = false) String nameKeyword,
            @RequestParam(required = false) String coefKeyword,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size) {
        return moduleService.searchModules(lang, nameKeyword, coefKeyword, PageRequest.of(page, size));
    }
}

关键细节说明

  • 嵌套字段查询:通过interventions.lang的路径格式定位嵌套文档中的字段
  • 模糊匹配规则:使用regex实现模糊查询,"i"参数表示不区分大小写
  • 数字类型模糊处理:coef为Integer类型,需先转为字符串再做正则匹配
  • 分页实现:通过Query.with(pageable)添加分页参数,单独查询总条数构建PageImpl分页对象

内容的提问来源于stack exchange,提问作者DrDray

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 19:04:58