ConditionalOperators返回null抛异常,如何实现按需映射聚合投影字段?
解决Spring Data MongoDB投影ConditionalOperators传null的异常问题
你遇到的"null values not supported for conditional operators"异常,是因为MongoDB的$cond操作符不允许将null作为分支返回值,而你代码里的.otherwise(null)直接违反了这个限制。
要实现当joined.isHeaderDocument为true时映射headerForm字段,否则不包含该字段的需求,推荐以下两种方案:
方案一:使用MongoDB 4.2+的$$REMOVE(推荐)
MongoDB 4.2及以上版本支持$$REMOVE变量,可在投影时直接移除不符合条件的字段,结合自定义AggregationExpression实现需求:
private static ProjectionOperation getProjectionOperation() { // 构建聚合表达式:条件满足时返回documentID,否则返回$$REMOVE移除该字段 AggregationExpression headerFormExpr = aggregationContext -> new Document("$cond", Arrays.asList( new Document("joined.isHeaderDocument", Boolean.TRUE), "$documentID", "$$REMOVE" )); return Aggregation.project() .and("doc").as("relationshipNumber") .and(headerFormExpr).as("headerForm"); }
方案二:兼容低版本MongoDB(<4.2)
如果你的MongoDB版本低于4.2,无法使用$$REMOVE,可以通过两步聚合实现:先投影所有字段(条件不满足时给headerForm设一个特殊占位值),再移除占位值对应的字段:
private static Aggregation getAggregation() { // 第一步:基础投影,条件不满足时headerForm设为空字符串 ProjectionOperation initialProject = Aggregation.project() .and("doc").as("relationshipNumber") .and(ConditionalOperators.when(Criteria.where("joined.isHeaderDocument").is(true)) .thenValueOf("documentID") .then("")) .as("headerForm"); // 第二步:仅保留非空的headerForm字段 ProjectionOperation finalProject = Aggregation.project() .and("relationshipNumber").as("relationshipNumber") .and(context -> new Document("$cond", Arrays.asList( new Document("$ne", Arrays.asList("$headerForm", "")), "$headerForm", "$$REMOVE" ))).as("headerForm"); return Aggregation.newAggregation(initialProject, finalProject); }
内容的提问来源于stack exchange,提问作者madhuri
相关产品推荐
相关产品推荐

