Spring数据排序操作超过最大大小

时间:2017-07-26 15:14:15

标签: java spring mongodb spring-data

我是一个非常新的Spring和Mongodb,我在从MongoDB中提取数据时遇到了问题。我正在尝试获取相当大量的数据,并且收到以下异常:

  ... 
   Query query = new Query();
    query.with(new Sort(Sort.Direction.DESC, "vin"));
        Criteria c = new Criteria().andOperator(Criteria.where("updateTime").gt(startDate),  
                Criteria.where("updateTime").lte(endDate));  

        query.addCriteria(c);

        return this.mongoOperations.find(query, VehicleStatus.class);
  • 执行程序错误:OperationFailed:排序操作使用的RAM超过最大33554432字节。添加索引,或指定较小的限制。嵌套异常是com.mongodb.MongoException:Executor错误:OperationFailed:排序操作使用的RAM超过最大33554432字节。添加索引,或指定较小的限制。

在进一步阅读后,似乎使用聚合是一个好主意,因为我可以允许磁盘使用临时存储。我认为允许磁盘空间可以解决这个问题,也许我错误地使用它?但是我现在收到以下错误:聚合结果超过最大文档大小(16MB)" ,"代码" :16389

 ...
 MatchOperation matchStage = Aggregation.match(new Criteria().andOperator(Criteria.where("updateTime").gt(startDate),  
                Criteria.where("updateTime").lte(endDate)));
        SortOperation sort = Aggregation.sort(Direction.DESC, "vin");

        Aggregation agg = Aggregation.newAggregation(VehicleStatus.class, matchStage, sort)
                .withOptions(Aggregation.newAggregationOptions().allowDiskUse(true).build());

        List<VehicleStatus> vs = this.mongoOperations.aggregate(agg, "vehicleStatus", VehicleStatus.class).getMappedResults();
        return vs;

我真的不知道如何处理这件事。如果两个查询都在给定的大小限制内,则它们都有效。如果有人有任何提示或建议,将不胜感激。如果您有任何疑问或需要任何其他代码,请告诉我们!

谢谢你

2 个答案:

答案 0 :(得分:4)

聚合管道的结果超过16MB,并且由于MongoDB文档的最大允许大小为16MB,因此抛出此异常。

所以,你有两个选择:

  • 减小输出的大小,这里有一种可能是使用Spring Data MongoDB的limit()方法来限制输出的大小
  • 使用MongoDB的$out operator将聚合结果通过管道传输到集合

您可以通过Spring的Mongo DB的外观调整您的代码以使用$out(注意:我没有验证此代码,但重要的是您必须提供类似于{1}的AggregationOperation我已在下面编码):

Aggregation agg = Aggregation.newAggregation(VehicleStatus.class, matchStage, sort, new    AggregationOperation() {
  @Override
  public DBObject toDBObject(AggregationOperationContext context) {
    return new BasicDBObject("$out", “outputCollection”);
  }
}).withOptions(Aggregation.newAggregationOptions().allowDiskUse(true).build());

答案 1 :(得分:1)

我最初标记为正确的答案确实有效,但我能够找到更简单的答案,索引!

所以对于有这个问题的其他人来说:

db.getCollection('myCollectionName')。createIndex({“key”:-1}) (我为此使用了robomongo)

所以在我的情况下,然后键是vin,因为我想按顺序排序,-1表示降序,1表示升序。