2

我有一个 ETL 过程,需要从一个非常大的 Mongo 集合(1.5 亿个文档)中提取数据。我最初使用 Spring data 的模板是这样的:

this.template.find(this.mongoQuery.limit(this.pageSize).skip(this.pageSize * this.currentPage++), MyModel.class, this.collection);

当我在我的开发环境中对 1700 万个文档运行 ETL 时,这很好用(每 100K 文档需要 20 秒——pageSize),但是在 1150 万条记录之后,它会从 20 秒到 4 分钟来检索下一页。此外,这根本无法扩展到 1.6 亿份实时文档。

我遇到的主要问题之一是我无法控制 mongo 集合的结构方式,并且我的过滤条件基于文档中多个属性日期属性的日期范围,并且这些日期没有索引,因为客户端使用此集合的人不会按这些日期过滤,只有我的 ETL。

我将实现更改为仅使用 java Mongo 驱动程序并将 batchSize 设置为 500K,这似乎表现更好,在我的开发环境中达到 1150 万后我没有达到那种减速。所以,我的代码变成了

cursor = this.template.getCollection(collection).find(mongoQuery.getQueryObject());
cursor.batchSize(pageSize);
//batch logic
List<MyModel> models = new ArrayList<MyModel>();
    for (DBObject result : cursor) {
        models.add(this.template.getConverter().read(MyModel.class, result));
        counter++;
        if (counter >= this.pageSize) {
            break;
        }
    }
    this.currentPage++;

    return models;

我还没有实时发布这个改动,所以我不知道它会表现得如何。使用没有在这个非常大的集合中索引属性的标准来收集我感兴趣的文档的最佳方法是什么?如果这不起作用,唯一的另一个想法是不通过标准并获取所有文档,遍历我的 ETL 中的 1.5 亿个文档并在那里进行过滤。

4

0 回答 0