尝试在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.THIS
和 ArrayOperators.Reduce.Variable.VALUE
可用。
使用上面的方法是正确的,或者你可以和Bson一起去。例如p->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 错误代码
如何在 Spring Boot 中自动增加 mongo db?
带有 MongoTemplate 的 Spring Boot
SpringBoot整合Ant Design Pro进行部署
NoSuchMethodException QueryDSL 与 Spring Boot 和 Spring Data Mongo