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
相关产品推荐
相关产品推荐

