spring-projects / spring-data-mongodb

Provides support to increase developer productivity in Java when using MongoDB. Uses familiar Spring concepts such as a template classes for core API usage and lightweight repository style data access.
https://spring.io/projects/spring-data-mongodb/
Apache License 2.0
1.62k stars 1.09k forks source link

NoSuchElementException throws while using @Aggregation to group #4546

Closed human-user closed 11 months ago

human-user commented 11 months ago

my case :

@Aggregation(value = "[{ \"$group\" : { \"_id\" : \"$taskStatus\", \"count\" : { \"$sum\" : 1}}}]")
AggregationResults<CountScanTaskRespDto> countByTaskStatus();
@Document("scan_task")
public class ScanTask {
    @Id
    private String id;
    private String name;
    private Integer taskStatus;
}

public class CountScanTaskRespDto {
    private Integer count;
}

It work well while using mongoTemplate.aggregate :

AggregationResults<CountScanTaskRespDto> result = mongoTemplate.aggregate(
        aggregation, ScanTask.class, CountScanTaskRespDto.class);
return result.getMappedResults();

exception stack log:

java.util.NoSuchElementException: null
    at java.base/java.util.LinkedHashMap$LinkedHashIterator.nextNode(LinkedHashMap.java:758) ~[na:na]
    at java.base/java.util.LinkedHashMap$LinkedKeyIterator.next(LinkedHashMap.java:778) ~[na:na]
    at org.springframework.data.mongodb.core.aggregation.AggregationOperation.getOperator(AggregationOperation.java:66) ~[spring-data-mongodb-4.1.1.jar:4.1.1]
    at org.springframework.data.mongodb.core.aggregation.AggregationPipeline.isOut(AggregationPipeline.java:165) ~[spring-data-mongodb-4.1.1.jar:4.1.1]
    at org.springframework.data.mongodb.core.aggregation.AggregationPipeline.isOutOrMerge(AggregationPipeline.java:99) ~[spring-data-mongodb-4.1.1.jar:4.1.1]
    at org.springframework.data.mongodb.repository.query.StringBasedAggregation.computeOptions(StringBasedAggregation.java:185) ~[spring-data-mongodb-4.1.1.jar:4.1.1]
    at org.springframework.data.mongodb.repository.query.StringBasedAggregation.doExecute(StringBasedAggregation.java:112) ~[spring-data-mongodb-4.1.1.jar:4.1.1]
    at org.springframework.data.mongodb.repository.query.AbstractMongoQuery.execute(AbstractMongoQuery.java:118) ~[spring-data-mongodb-4.1.1.jar:4.1.1]
    at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:136) ~[spring-data-commons-3.1.1.jar:3.1.1]
    at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:120) ~[spring-data-commons-3.1.1.jar:3.1.1]
    at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:164) ~[spring-data-commons-3.1.1.jar:3.1.1]
    at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:143) ~[spring-data-commons-3.1.1.jar:3.1.1]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.0.10.jar:6.0.10]
    at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:72) ~[spring-data-commons-3.1.1.jar:3.1.1]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.0.10.jar:6.0.10]
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97) ~[spring-aop-6.0.10.jar:6.0.10]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.0.10.jar:6.0.10]
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:244) ~[spring-aop-6.0.10.jar:6.0.10]
    at jdk.proxy2/jdk.proxy2.$Proxy126.countByTaskStatus(Unknown Source) ~[na:na]
christophstrobl commented 11 months ago

The @Aggregation accepts a String array containing the individual pipeline stages as outlined below.

@Aggregation("{ '$project': { '_id' : '$lastname' } }")
List<Person> ...

@Aggregation(pipeline = {
        "{ '$group': { '_id' : '$lastname', names : { $addToSet : '$?0' } } }", 
        "{ '$sort' : ... }
})
List<Person> ...

Please remove the outer square brackets to archive the expected behaviour.

human-user commented 11 months ago

@christophstrobl It worked well after remove the outer square. I have saw the pull request. Could you tell me why not support to parse the json array instead of throw a IllegalStateException?