Spring Data MongoDB聚合match查询嵌套ObjectId字符串转换异常问题
问题根因
- 对于顶层文档的
_id字段,Spring Data MongoDB默认支持String和ObjectId的自动类型转换,直接传入String列表即可正常生成$oid格式的查询条件。但嵌套对象的_id字段没有默认的类型转换规则,直接传入String列表无法匹配到数据库中存储的ObjectId类型值。 - 你遇到的
$in生成二维数组的问题,是部分版本Spring Data MongoDB的Criteria.in()方法的已知缺陷:当传入参数为Collection类型时,会错误将整个集合作为单个元素塞入$in的数组结构中,导致多套了一层数组,查询失效。
修复方案
方案1:传入ObjectId数组(兼容性最好,无需修改实体)
直接将待查询的ID转换为ObjectId数组后传入in方法,规避Collection类型触发的嵌套数组bug:
List<String> typeIds = Arrays.asList("618b99a3b4c24465b074b246", "60ad10ffc723877d8a977149"); List<AggregationOperation> aggregateOperations = new ArrayList<>(); // 转换为ObjectId数组 ObjectId[] oidArray = typeIds.stream().map(ObjectId::new).toArray(ObjectId[]::new); Criteria criteria = Criteria.where("type._id").in(oidArray); aggregateOperations.add(Aggregation.match(criteria)); Aggregation aggregation = Aggregation.newAggregation(aggregateOperations); mongoTemplate.aggregate(aggregation, "products", ProductListDTO.class);
方案2:修改实体字段类型(后续无需手动转换类型)
将ProductType实体的ID字段类型改为ObjectId,Spring Data MongoDB会自动处理嵌套字段的类型转换,直接传入String列表即可正常查询:
@Document(collection = "product_types") public class ProductType { @Id private ObjectId id; public ObjectId getId() { return id; } public void setId(ObjectId id) { this.id = id; } }
修改后查询代码可以简化为:
List<String> typeIds = Arrays.asList("618b99a3b4c24465b074b246", "60ad10ffc723877d8a977149"); List<AggregationOperation> aggregateOperations = new ArrayList<>(); // 直接传入String列表即可,Spring会自动转换为ObjectId Criteria criteria = Criteria.where("type._id").in(typeIds); aggregateOperations.add(Aggregation.match(criteria)); Aggregation aggregation = Aggregation.newAggregation(aggregateOperations); mongoTemplate.aggregate(aggregation, "products", ProductListDTO.class);
两种方案执行后,生成的查询语句都会和你预期的一致,不会出现二维数组的问题。
内容的提问来源于stack exchange,提问作者kenn3th
相关产品推荐
相关产品推荐

