You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Spring Data Mongo的findAll()查询中使用{allowDiskUse: true}

解决CrudRepo.findAll()排序内存超限问题

遇到的异常:

com.mongodb.MongoQueryException: Query failed with error code 292 and error message 'Executor error during find command :: caused by :: Sort exceeded memory limit of 104857600 bytes, but did not opt in to external sorting.'

Spring Data提供的CrudRepo.findAll()默认方法无法直接配置allowDiskUse: true,因为这类通用方法没有暴露MongoDB底层参数配置。不过可以通过以下两种方式实现需求:

  • 自定义查询方法,借助MongoTemplate配置参数
    如果是普通查询加排序场景,可通过MongoTemplate构建查询并开启磁盘使用:

    import org.springframework.data.mongodb.core.MongoTemplate;
    import org.springframework.data.mongodb.core.query.Query;
    import org.springframework.data.domain.Sort;
    
    // 在Service或自定义Repository实现类中
    public List<YourEntity> findAllWithDiskSorting() {
        Query query = new Query();
        // 添加排序条件,示例为按createTime降序
        query.with(Sort.by(Sort.Direction.DESC, "createTime"));
        // 开启allowDiskUse配置
        query.withHint(new org.bson.Document("allowDiskUse", true));
        return mongoTemplate.find(query, YourEntity.class);
    }
    

    如果涉及聚合操作,直接通过AggregationOptions开启磁盘使用:

    import org.springframework.data.mongodb.core.aggregation.Aggregation;
    import org.springframework.data.mongodb.core.aggregation.AggregationOptions;
    
    public List<YourEntity> aggregateWithDiskUse() {
        Aggregation aggregation = Aggregation.newAggregation(
            Aggregation.sort(Sort.by("createTime").descending())
            // 按需添加其他聚合步骤
        ).withOptions(AggregationOptions.builder().allowDiskUse(true).build());
        
        return mongoTemplate.aggregate(aggregation, "your_collection_name", YourEntity.class)
                           .getMappedResults();
    }
    
  • 扩展CrudRepository,自定义实现类
    先定义自定义接口:

    public interface CustomYourEntityRepository {
        List<YourEntity> findAllWithAllowDiskUse();
    }
    

    让CrudRepository继承该接口:

    public interface YourEntityRepository extends CrudRepository<YourEntity, String>, CustomYourEntityRepository {
    }
    

    最后实现自定义接口,通过MongoTemplate完成查询:

    public class CustomYourEntityRepositoryImpl implements CustomYourEntityRepository {
        
        private final MongoTemplate mongoTemplate;
    
        public CustomYourEntityRepositoryImpl(MongoTemplate mongoTemplate) {
            this.mongoTemplate = mongoTemplate;
        }
    
        @Override
        public List<YourEntity> findAllWithAllowDiskUse() {
            Query query = new Query();
            query.withHint(new org.bson.Document("allowDiskUse", true));
            return mongoTemplate.find(query, YourEntity.class);
        }
    }
    

    业务代码中即可直接调用yourEntityRepository.findAllWithAllowDiskUse()启用磁盘排序。

注意:如果你的findAll()调用带有Sort参数(如findAll(Sort sort)),排序操作正是触发内存超限的核心原因,必须通过上述方式开启allowDiskUse才能绕过限制。

内容的提问来源于stack exchange,提问作者Sandeep Chakraborty

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 06:40:44