尝试在springboot mongo中使用projectionoperation聚合reduce时出错

Posted

技术标签:

【中文标题】尝试在springboot mongo中使用projectionoperation聚合reduce时出错【英文标题】:Error while trying to aggregate reduce with projectionoperation in springboot mongo 【发布时间】:2020-11-06 04:36:15 【问题描述】:

我想在春季编写以下 mongo 查询

db.getCollection('mydb').aggregate([
$match: tag :"123",
$group: _id:"$tag" , message:$addToSet: "$message",
   $project: 
    "tag": "$tag",
    "message": 
      "$reduce": 
        "input": "$message",
        "initialValue": [],
        "in":  "$concatArrays": [ "$$value", "$$this" ] 
      
    
  

mydb 集合中很少有示例文档看起来像这样

    doc1: 
     tag:"123",
    message: [msg1,msg2]
    
    doc2:
     tag:"123",
    message: [msg3,msg4, msg5]
    

我的目标是按标签分组并将消息字段合并到单个数组中。 输出:

    
    tag:"123",
    message: [msg1,msg2,msg3,msg4, msg5]
    

春天我试过了,

        List<AggregationOperation> operationList = new ArrayList<>();
        MatchOperation matchStage = Aggregation.match(new Criteria("tag").is("123"));
        GroupOperation groupingStage = group(Fields.fields("tag"))
                .first("tag").as("tag")
                .push("message").as("message")
             
        ArrayOperators.Reduce reduce = ArrayOperators.Reduce.arrayOf("message")
                .withInitialValue(new ArrayList<>())
                .reduce(ArrayOperators.ConcatArrays.arrayOf("$$value")
                        .concat("$$target");
       ProjectionOperation projectionOperation =project("tag").and(reduce).as("message");
        operationList.add(matchStage);
        operationList.add(groupingStage);
        operationList.add(projectionOperation);
        Aggregation aggregation = Aggregation.newAggregation(operationList);
        AggregationResults<SomeClass> result = mongoTemplate.aggregate(aggregation,"mydb", SomeClass.class)

 

       This gives exception
        java.lang.IllegalArgumentException: Invalid reference '$$value'!
            at org.springframework.data.mongodb.core.aggregation.ExposedFieldsAggregationOperationContext.getReference(ExposedFieldsAggregationOperationContext.java:100)
            at org.springframework.data.mongodb.core.aggregation.ExposedFieldsAggregationOperationContext.getReference(ExposedFieldsAggregationOperationContext.java:72)
            at org.springframework.data.mongodb.core.aggregation.AbstractAggregationExpression.unpack(AbstractAggregationExpression.java:73)

如果没有项目操作,它可以正常工作,但我得到的结果不是我们想要的.. 如下所示

 
    tag:"123",
    message: [[msg1,msg2],
             [msg3,msg4, msg5]]
 

【问题讨论】:

.reduce(ArrayOperators.ConcatArrays.arrayOf($$value)...:我认为错误消息表明'$$value' 的使用有问题。 API 说:在评估 in 表达式期间,变量引用 ArrayOperators.Reduce.Variable.THISArrayOperators.Reduce.Variable.VALUE 可用。 使用上面的方法是正确的,或者你可以和Bson一起去。例如p-&gt;new Document("$project", new Document("tage","$tags").append("message",new Document("$reduce",new Document("input","$message").append("initialValue",[]).append(.....).....)) 【参考方案1】:

您可以使用 $unwind 完全避免 $reduce:

db.getCollection('mydb').aggregate([
  $match: tag :"123",
  $unwind: "$message",
  $group: _id:"$tag" , message:$addToSet: "$message",
   $project: 
    "_id": 0
    "tag": "$_id",
    "message": 1
  
])

【讨论】:

谢谢乔。实际上,我需要在文档中获得总和的更多字段,因此我不得不稍微修改您的解决方案。但是您的解决方案帮助我找到了解决方案。

以上是关于尝试在springboot mongo中使用projectionoperation聚合reduce时出错的主要内容,如果未能解决你的问题,请参考以下文章

Springboot 容器使用 docker-compose 连接到 mongo 容器的 503 错误代码

Springboot mongo异常与Docker

如何在 Spring Boot 中自动增加 mongo db?

带有 MongoTemplate 的 Spring Boot

SpringBoot整合Ant Design Pro进行部署

NoSuchMethodException QueryDSL 与 Spring Boot 和 Spring Data Mongo