rohit
rohit

Reputation: 1003

Spring data mongodb - The 'cursor' option is required

I am trying to execute an aggregate operation using Spring Data MongoDB 3.6-rc4.

Aggregation agg = newAggregation(
    lookup("orders", "orderId", "_id", "order") 
);
List<BasicDBObject> results = mongoOperations.aggregate(agg, "transactions", BasicDBObject.class).getMappedResults();

But get the following error on running the query

2017-11-24 17:03:41,539 WARN  org.springframework.data.mongodb.core.MongoTemplate : Command execution of { "aggregate" : "transactions" , "pipeline" : [ { "$lookup" : { "from" : "orders" , "localField" : "orderId" , "foreignField" : "_id" , "as" : "order"}}]} failed: The 'cursor' option is required, except for aggregate with the explain argument
2017-11-24 17:03:41,574 ERROR org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: Command execution failed:  Error [The 'cursor' option is required, except for aggregate with the explain argument], Command = { "aggregate" : "transactions" , "pipeline" : [ { "$lookup" : { "from" : "orders" , "localField" : "orderId" , "foreignField" : "_id" , "as" : "order"}}]}; nested exception is com.mongodb.MongoCommandException: Command failed with error 9: 'The 'cursor' option is required, except for aggregate with the explain argument' on server localhost:27017. The full response is { "ok" : 0.0, "errmsg" : "The 'cursor' option is required, except for aggregate with the explain argument", "code" : 9, "codeName" : "FailedToParse" }] with root cause
com.mongodb.MongoCommandException: Command failed with error 9: 'The 'cursor' option is required, except for aggregate with the explain argument' on server localhost:27017. The full response is { "ok" : 0.0, "errmsg" : "The 'cursor' option is required, except for aggregate with the explain argument", "code" : 9, "codeName" : "FailedToParse" }
    at com.mongodb.CommandResult.getException(CommandResult.java:80) ~[mongo-java-driver-3.5.0.jar:na]
    at com.mongodb.CommandResult.throwOnError(CommandResult.java:94) ~[mongo-java-driver-3.5.0.jar:na]
    at org.springframework.data.mongodb.core.MongoTemplate.handleCommandError(MongoTemplate.java:2100) ~[spring-data-mongodb-1.10.8.RELEASE.jar:na]
    at org.springframework.data.mongodb.core.MongoTemplate.aggregate(MongoTemplate.java:1577) ~[spring-data-mongodb-1.10.8.RELEASE.jar:na]
    at org.springframework.data.mongodb.core.MongoTemplate.aggregate(MongoTemplate.java:1505) ~[spring-data-mongodb-1.10.8.RELEASE.jar:na]

Thanks in advance!!

Upvotes: 26

Views: 41219

Answers (13)

gelin
gelin

Reputation: 111

  1. Use Spring Boot 2.0.0 or later.
  2. Add AggregationOptions with cursor to your Aggregation:
AggregationOptions aggregationOptions = AggregationOptions.builder()
    .allowDiskUse(true)
    .cursor(new Document())
    .build();
Aggregation aggregation = Aggregation.newAggregation(aggregationOperations)
    .withOptions(aggregationOptions);
  1. Call aggregateStream() (not aggregate()) method of MongoOperations. This method utilizes the cursor responded by MongoDB:
mongoOps.aggregateStream(aggregation, "collection", MyEntity.class)

Upvotes: 0

Nestor Milyaev
Nestor Milyaev

Reputation: 6595

I've tried all above (short of changing the code to using a cursor) to no avail.

In the end, I had to upgrage

'mongo-java-driver'       : '3.6.2'

Then it worked.

Upvotes: 0

Pratik Saxena
Pratik Saxena

Reputation: 191

Upgrading the spring boot version didn't work for me. Changing outputmode as cursor as providing a cursor is mandatory, worked. Verified in mongo 3.6

List<DBObject> list = new ArrayList<DBObject>();
list.add(unwind.toDBObject(Aggregation.DEFAULT_CONTEXT));
list.add(group.toDBObject(Aggregation.DEFAULT_CONTEXT));
list.add(sort.toDBObject(Aggregation.DEFAULT_CONTEXT));

DBCollection col = mongoTemplate.getCollection("users");

Cursor cursor = col.aggregate(list, AggregationOptions.builder().allowDiskUse(true).outputMode(OutputMode.CURSOR).build());

List<AggregationResultVO> result = new ArrayList<AggregationResultVO>();

while(cursor.hasNext()) {
     DBObject object = cursor.next();
     result.add(new AggregationResultVO(object.get("aggregationResultId").toString()));
}

Upvotes: 4

krishan
krishan

Reputation: 59

Your command no longer works due to a change in mongodb driver change in version 3.6. You need to invoke it from dbCollection.aggregate(...) method instead.

Upvotes: 0

Lucas Vall
Lucas Vall

Reputation: 69

If you are having this issue and you are using Studio 3T, there is an option in the Options tab, just check it:

enter image description here

Upvotes: 0

Andrei Maimas
Andrei Maimas

Reputation: 695

Solved the issue by upgrading spring boot to the '2.1.3.RELEASE' version.

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.3.RELEASE</version>
        <!--<version>1.5.10.RELEASE</version>-->
        <relativePath></relativePath>
    </parent>

Upvotes: 0

mhvr
mhvr

Reputation: 21

You can use cursor option available with aggregate query pipeline.

{cursor: { batchSize: batch_size }}

https://docs.mongodb.com/manual/reference/method/db.collection.aggregate/

Aggregation.newAggregation(AggregationOperation... operations).withOptions(new AggregationOptions(false,false,new Document().append("batchSize" , batch_size))) may help in this case

Upvotes: 2

Giahu
Giahu

Reputation: 1

I have also faced this type of error when using org.springframework.data version 1.10.3.RELEASE. And then i have changed version to 2.0.5.RELEASE and my problem was solved.

Upvotes: 0

amit kumar
amit kumar

Reputation: 79

Just updating the spring boot version works for me.
This is the version that I have used and worked....
<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.10.RELEASE</version>
    </parent>

Upvotes: 1

Atari
Atari

Reputation: 31

It seems Pull Request mentionned by @mp911de has been release in version 1.10.10 of Spring Data MongoDB. So you can either

  • upgrade your Spring Data MongoDB dependency to 1.10.10.RELEASE
  • upgrade your spring-boot-starter-data-mongodb dependency to 1.5.10.RELEASE

Upvotes: 3

Andrei Maimas
Andrei Maimas

Reputation: 695

I was using:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.8.RELEASE</version>
    <relativePath></relativePath>
</parent>

Then after upgraded my dependency to a higher version, the issue was resolved:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.10.RELEASE</version>
    <relativePath></relativePath>
</parent>

Upvotes: 11

Adarsh Patel
Adarsh Patel

Reputation: 113

I have also faced this type of error when using Mongodb version 3.6.2.

Check your version of org.springframework.data in pom.xml

For me, i have changed org.springframework.data version to 2.0.3.RELEASE and my problem was solved.

Upvotes: 1

mp911de
mp911de

Reputation: 18119

MongoDB changed in 3.6 how the aggregation command works. Aggregations require now a cursor. We adapted Spring Data MongoDB 2.1 but not previous versions.

Aggregations must be invoked through the collection's aggregate(…) method instead of calling the command directly. This is also the reason why we didn't backport the change. executeCommand(…) is no longer called and we don't want to break compatibility in a bugfix release.

The easiest approach for you can be to override the aggregate(…) method and call the appropriate method, DBCollection.aggregate(…) with the mapped aggregation pipeline.

Upvotes: 25

Related Questions