当使用spring-data-mongodb的MongoTemplate执行MapReduce操作时,该方法返回一个MapReduceResults对象。
在我的用例中,未使用该对象(及其内容)(结果与数据库上的现有集合合并)。
MongoDB 驱动程序似乎向结果返回了一个游标(无数据),但 spring 库将此游标解析为实际的数据库对象。
这会导致大量数据通过网络传递,并且调用作业会因 OutOfMemoryError 而失败。
是否有某种方法(无需直接下降到 MongoDB 驱动程序)来限制 Spring 层返回给调用方法的数据库对象的数量?
- mongo-java-driver-2.12.1
- spring-data-mongodb-1.5.1.RELEASE
更新: 我认为这是一个相当普遍的问题的假设是错误的。
这是我正在运行的代码。这 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);
最佳答案
无需下拉至驱动程序。
这个问题可以通过扩展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 类移植一些私有(private)方法,以便这个新类可以访问它们。
关于java - 如何限制Spring data Mongo的map reduce方法返回的MapReduceResults的大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25122854/