java - 如何限制Spring data Mongo的map reduce方法返回的MapReduceResults的大小

标签 java mongodb spring-data-mongodb

当使用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/

相关文章:

java - 提供 BufferedImage 时 Spring MVC 内容协商失败

java - 在雅虎日历中创建 Activity

python - 使用 pymongo 读取和更新 mongodb 文档的最佳方法

java - MongoDB with Spring Data - 没有信号量来获取数据库连接

java - 尝试使用 GUI 运行 Java 实用程序时出现 X11 Frwarding 错误

java - 访问 Restful Web 服务时出现 404 错误

arrays - 查询所有数组项都大于指定条件的地方

javascript - 如果我有一个字符串形式的 mongo 文档 ID,我该如何将其作为 _id 查询?

使用 Spring Data 的 Mongodb 文档版本控制

mongodb - 我想要使​​用 spring 数据从 mongodb 中获得一个字段的不同值的结果