MongoTemplate如何查询指定嵌套对象并返回符合条件的内容?
解决Spring Boot中MongoDB嵌套数组的精准查询问题
问题场景
在Spring Boot开发中,使用MongoTemplate的Query/Criteria查询时,只能获取整个文档,但需要根据指定条件筛选嵌套数组中的元素,只返回符合条件的部分内容。
示例文档结构
{ "_id": { "$oid": "<Some Object Id>" }, "identifier": "string1", "createTime": { "$date": "2024-02-23T02:34:50.225Z" }, "properties": [ { "age": "28" }, { "age": "18" } ] }
需求说明
根据identifier字段定位文档,仅返回满足properties.age == "28"的内容,预期结果如下:
{ "_id": { "$oid": "<Some Object Id>" }, "properties": [ { "age": "28" } ] }
尝试的代码
Criteria criteria = Criteria.where("identifier").is("string1").and("properties.xxx").is("value"); Query query = Query.query(criteria); List<Product> objects = mongoTemplate.find(query, Product.class);
解决方案
单纯用Query/Criteria只能过滤出包含符合条件元素的整个文档,无法直接筛选数组内的元素,必须配合投影或聚合操作实现需求:
方法1:使用$elemMatch投影(返回第一个匹配元素)
适合只需要数组中第一个符合条件的元素的场景:
Query query = new Query(Criteria.where("identifier").is("string1")); // 指定返回_id字段,以及匹配条件的properties元素 query.fields().include("_id").elemMatch("properties", Criteria.where("age").is("28")); List<Product> result = mongoTemplate.find(query, Product.class);
方法2:使用$filter聚合(返回所有匹配元素,推荐)
如果需要返回数组中所有符合条件的元素,使用MongoDB聚合框架的$filter操作符:
Aggregation aggregation = Aggregation.newAggregation( // 第一步:匹配指定identifier的文档 Aggregation.match(Criteria.where("identifier").is("string1")), // 第二步:过滤properties数组,仅保留age=28的元素 Aggregation.project("_id") .and(ArrayOperators.Filter.filter("properties") .as("item") .by(Criteria.where("item.age").is("28"))) .as("properties") ); // 替换your_collection_name为实际集合名称 AggregationResults<Product> results = mongoTemplate.aggregate(aggregation, "your_collection_name", Product.class); List<Product> resultList = results.getMappedResults();
注意事项
- 确保
Product实体类的字段与MongoDB文档结构映射正确; - 两种方法按需选择:
$elemMatch适合单匹配场景,聚合$filter支持多匹配元素返回。
内容的提问来源于stack exchange,提问作者5Hang
相关产品推荐
相关产品推荐

