Spring Data MongoDB - 需要使用“cursor”选项

24

我正在尝试使用Spring Data MongoDB 3.6-rc4执行一个聚合操作。

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

但在运行查询时遇到了以下错误

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]

提前感谢!!


你能提供更多的上下文吗?你正在使用哪个版本的MongoDB? - mp911de
MongoDB的版本是v3.6.0-rc4。 - rohit
13个回答

25

MongoDB在3.6版本中改变了聚合命令的工作方式。现在需要使用光标进行聚合操作。我们已经修改了Spring Data MongoDB 2.1,但之前的版本并没有进行修改。

现在必须通过集合的aggregate(…) 方法来调用聚合操作,而不能直接调用命令。这也是为什么我们没有将此更改移植到旧版本的原因之一。executeCommand(…)不再被调用,我们不想在一个修复错误版本中破坏兼容性。

对于您来说,最简单的方法可能是覆盖aggregate(…)方法并调用适当的方法,即DBCollection.aggregate(…)与映射的聚合管道。


MongoDB 3.4是否与当前版本的Spring Data兼容,并支持聚合? - rohit
是的,它得到了完全支持。 - mp911de
1
大家好。最近我遇到了同样的问题。据我所知,我应该采取以下其中一种方法:a)等待Spring Data MongoDB 2.1发布,b)创建一个继承自MongoTemplate的类,并通过引入PR https://github.com/spring-projects/spring-data-mongodb/pull/515中包含的所有更改来重写aggregate()方法。 我是正确的吗? - Lesha Pipiev
今天起,固定的Spring Data版本已经发布。 - mp911de
@mp911de,感谢您的快速回复。但是还有另一个问题 :) 我正在使用spring-boot-starter-data-mongodb通过spring-data-mongodb,它目前与spring-data-mongodb v1.10.9耦合在一起。顺便说一下,在https://mvnrepository.com/artifact/org.springframework.data/spring-data-mongodb-parent中我没有看到v2.1.0。再次感谢。 - Lesha Pipiev
你好 @mp911de,能否展示一下使用 dbcollection.aggregate 的例子?我尝试更新了 spring-data,但应用程序没有更新,我们需要更新 spring-boot-2,而我有其他尚未支持的库(apache-camel)。 - Renato Garcia

11

我正在使用:

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

然后,升级我的依赖到更高的版本后,问题得到解决:

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

1
MongoDB 3.6需要Spring 1.5.10.RELEASE来执行聚合操作。 - Nandhu

4

升级Spring Boot版本对我没有用,将输出模式更改为光标,并提供必需的光标,这样才有效。在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()));
}

3

看起来@mp911de提到的Pull Request已经在Spring Data MongoDB 1.10.10版本中发布。

因此,您可以选择:

  • 将Spring Data MongoDB依赖项升级到1.10.10.RELEASE
  • 将spring-boot-starter-data-mongodb依赖项升级到1.5.10.RELEASE

这两个具体的要点对我很有帮助。谢谢@Atari。 - veritas

1
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>

我们已将MongoDB从3.4升级到5.0,遇到了相同的问题。但是这个版本更改解决了这个问题。非常感谢您提供的解决方案,您帮我省去了大量的代码更改,真是救了我的一天。 - Sumit Sharma

1

您可以使用聚合查询管道中提供的游标选项。

{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))) 可能会有所帮助。

1
我在使用Mongodb版本3.6.2时也遇到了这种错误。请检查pom.xml中org.springframework.data的版本。
对于我来说,我将org.springframework.data的版本更改为2.0.3.RELEASE,问题得到了解决。

0

通过将Spring Boot升级到“2.1.3.RELEASE”版本解决了该问题。

<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>

0

由于mongodb驱动程序在版本3.6中发生了更改,您的命令不再起作用。 您需要改为从dbCollection.aggregate(...)方法调用它。


1
可能是一条注释 - quant

0
我已经尝试了上述所有方法(除了改变代码以使用游标),但都没有成功。
最后,我不得不升级。
'mongo-java-driver'       : '3.6.2'

然后它就工作了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接