当使用spring-data-mongodb的MongoTemplate执行map reduce操作时,该方法返回一个MapReduceResults对象。
在我的用例中,不使用此对象(及其内容)(结果与数据库上的现有集合合并)。
MongoDB驱动程序似乎向结果返回游标(无数据),但弹出库将此游标解析为实际的数据库对象。
这会导致大量数据通过网络传递,并且由于OutOfMemoryError而导致调用作业失败。
有没有办法(不直接下载到MongoDB驱动程序)来限制Spring层返回给调用方法的数据库对象的数量?
更新 : 似乎我的假设是这是一个相当普遍的问题是不正确的。
这是我正在运行的代码。 3个JS函数存储在文件中,并由loadFile()方法作为字符串加载。
我在这里添加了结果分配的RHS(它不在我的代码中,因为我不需要/使用结果)。我喜欢mapRecuce方法的一个版本,它不会返回任何内容。
MapReduceOptions options = MapReduceOptions.options();
options.outputTypeReduce();
options.finalizeFunction(loadFile(finalizeFunctionFilename));
options.outputCollection(output_collection_name);
List<DBObject> results = mongoTemplate.mapReduce(query,
input_collection_name,
loadFile(mapFunctionFilename),
loadFile(reduceFunctionFilename),
options,
DBObject.class);
答案 0 :(得分:2)
无需下载给司机。
可以通过扩展MongoTemplate类并覆盖mapReduce方法来解决此问题。
显然,在升级库时,应该小心地将任何更改移植到这个新类。
新方法如下所示:
@Override
public <T> MapReduceResults<T> mapReduce(Query query, String inputCollectionName, String mapFunction,
String reduceFunction, MapReduceOptions mapReduceOptions, Class<T> entityClass) {
if (mapReduceOptions.getOutputType() == OutputType.INLINE) {
// if output type is inline then no need to suppress results
return super.mapReduce(query, inputCollectionName, mapFunction, reduceFunction, mapReduceOptions, entityClass);
}
String mapFunc = replaceWithResourceIfNecessary(mapFunction);
String reduceFunc = replaceWithResourceIfNecessary(reduceFunction);
DBCollection inputCollection = getCollection(inputCollectionName);
MapReduceCommand command = new MapReduceCommand(inputCollection, mapFunc, reduceFunc,
mapReduceOptions.getOutputCollection(), mapReduceOptions.getOutputType(), null);
DBObject commandObject = copyQuery(query, copyMapReduceOptions(mapReduceOptions, command));
if (logger.isDebugEnabled()) {
logger.debug("Executing MapReduce on collection [{}], mapFunction [{}], reduceFunction [{}]",
command.getInput(), mapFunc, reduceFunc);
}
CommandResult commandResult = executeCommand(commandObject);
handleCommandError(commandResult, commandObject);
if (logger.isDebugEnabled()) {
logger.debug("MapReduce command result = [{}]", serializeToJsonSafely(commandObject));
}
return new MapReduceResults<>(new ArrayList<T>(), commandResult);
}
您还需要在原始MongoTemplate类中移植一些私有方法,以便这个新类可以访问它们。