1

我有一个在 MongoDB Shell 中工作的查询,但是当我增加要返回的文档数量时,它使用 Spring Data MongoDB 抛出“聚合结果超过最大文档大小 (16MB)”异常。

这是返回没有错误的 shell 查询:

db.myCollection.aggregate([{"$skip":0},{"$limit":10000},{"$match":{"_id"="550b2552e4b03562d6329a39"}}], {"allowDiskUse":true})

这是 Spring 数据片段:

List<AggregrationOperation> ops = new ArrayList<AggregationOperation>();
ops.add(new SkipOperation(0));
ops.add(new LimitOperation(10000));
ops.add(new MatchOperation(Criteria.where("_id").is("550b2552e4b03562d6329a39")));

TypeAggregation<MyCollection> aggregation = Aggregation.newAggregation(MyCollection.class, ops).withOptions(Aggregation.newAggregationOptions().allowDiskUse(true).build());

AggregationResults<MyCollection> result = mongoTemplate.aggregate(aggregation, MyCollection.class);
List<MyCollection> myResults = result.getMappedResults()

当我限制说 100 或 1000 条记录时,一切正常。当我增加到 10,000 时,我得到“聚合结果超过最大文档大小 (16MB)”异常。

以下是我正在使用的版本供参考:

MongoDB = 3.0.0
Mongo Java Driver = 2.13.0
Spring Data MongoDB = 1.6.0
Spring Data Commons = 1.9.0

更新:

背景:我之所以选择聚合解决方案,是因为我在使用 find() 时超出了 32MB 的排序限制。我知道添加索引可以解决这个问题。不幸的是,此解决方案无法扩展。我想对列表网格中的所有列进行排序,这意味着要索引 10 多列。当然,从 UI 我可以将排序限制为特定列,但我再次试图避免该解决方案,因此我尝试了聚合。

看来使用光标是我唯一的解决方案。谁能确认 Spring Data MongoDB 不提供直接游标支持,这意味着我必须使用 MongoDB 的 API?

4

2 回答 2

2

我在使用 RoboMongo(mongo 客户端)时遇到了同样的问题。尝试使用db.runCommand()而不是.aggregate().

似乎在某些客户端上使用聚合方法会将一些数据添加到查询中,而 allowDiskUse 将被忽略。

当我使用 ranCommand 时,它运行良好:

db.runCommand(
   { aggregate: "collection_name",
     pipeline: [
            {$group: ...}, 
            {$match: ...},
            {$group: ...}
           ],
     allowDiskUse: true
   }
于 2015-11-30T13:18:03.153 回答
1

您可以使用outputMode(AggregationOptions.OutputMode.CURSOR)作为输出选项,而不是默认使用有限的 16MB 文档。请参阅聚合光标用法

Aggregation.newAggregationOptions().outputMode(AggregationOptions.OutputMode.CURSOR).allowDiskUse(true).build()
于 2015-03-24T06:35:57.407 回答