MongoDB 排序超过内存限制

281 阅读1分钟

问题:MongoDB 排序超过内存限制,报错

报错信息:

Sort exceeded memory limit of 104857600 bytes, but did not opt in to external sorting. Aborting operation. Pass allowDiskUse:true to opt in.

解决方案:

mongo 对大数据集进行 aggregate 集合操作,处理各 stage 阶段中,为了避免 pipeline 的 stage 的内存使用过大而报错。需要设置 allowDiskUse 为 true ,使用系统缓存,以临时文件进行存储。

mongo 语句
db.message.aggregate([
	{
		$sort: {
			"seqno": -1,
			"version": -1
		}
	},
	{
		$group: {
			_id: {"seqno": "$seqno"},
			name: {$first: "$name"},
			seqno: {$first: "$seqno"}
		}
	}
],{
	allowDiskUse: true
})
Java 代码

Spring Data MongoDB 2.0 以上版本:

// 设置allowDiskUse=true使用系统缓存,以临时文件进行存储
AggregationOptions options = AggregationOptions.builder().allowDiskUse(true).build();

// 排序
Sort sort = new Sort(Sort.Direction.DESC, Arrays.asList("seqno", "version"));

// 分组
GroupOperation groupOperations = Aggregation.group("seqno");
groupOperations = groupOperations.first("seqnon").as("seqno");
groupOperations = groupOperations.first("name").as("name");
groupOperations = groupOperations.first("version").as("version");

Aggregation newAggregation = Aggregation.newAggregation(
      // 先按 seqno、version排序,后分组取第一条,即 version 最大的那条记录
      Aggregation.sort(sort),
      groupOperations
).withOptions(options);

Spring Data MongoDB 2.0 以下版本:

AggregationOptions aggregationOptions = new AggregationOptions(true, false, null);