Spring 批量 Mongo DB 到 .csv 到电子邮件

Spring Batch Mongo DB to .csv to email

这是我的问题陈述,

-第一步: 调用 mongo 数据库并获取当天的所有文档(基本上是一个请求)。

-第2步: 对于上面的每个文档,对不同的 mongodb 进行另一个调用,最终获取约 70k 个文档。

-第3步: 然后将上述 70k 文档(一些字段)分块处理以创建 .csv 文件。

-第4步: 然后这个 .csv 文件将存储在驱动器中,位置信息将通过电子邮件发送给用户。

-第5步: 对步骤 1 中的每个文档重复步骤 2 到 4。

为了实现这一点,我正在探索 Spring 批处理选项(更乐观的性能)但无法弄清楚该怎么做。任何专业建议/指导都会更有帮助。

谢谢,

据我所知,第 2 步到第 4 步是一个 MongoItemReader(将文档获取到 Mongo),处理一些字段和一个 CSV 项目编写器。所有这三个任务都应该是一个步骤,并且应该 运行 分块。

MongoItemReader 应该是这样的:

@Bean
@StepScope
public MongoItemReader<ReportFiles> reader(MongoTemplate mongoTemplate) {
    Criteria expiredFiles = Criteria.where("DateCreated").lte(expiredDate);
    HashMap<String, Sort.Direction> sortMap = new HashMap<>();
    sortMap.put("ReportFiles", Sort.Direction.DESC);
    MongoItemReader<ReportFiles> reader = new MongoItemReader<>();
    reader.setTemplate(mongoTemplate);
    reader.setSort(sortMap);
    reader.setTargetType(ReportFiles.class);
    reader.setQuery(Query.query(expiredFiles).getQueryObject().toString());
    return reader;
}

处理器对字段做一些事情:

@Override
public Docuement process(Docuement doc) {
    // Do some stuff with doc
    return doc;
}

和平面 FileitemWriter

@Bean
public FlatFileItemWriter<Document> writer(Resource outputResource) 
{
    FlatFileItemWriter<Document> writer = new FlatFileItemWriter<>();
    writer.setResource(outputResource);
    writer.setAppendAllowed(true);
    writer.setLineAggregator(new DelimitedLineAggregator<Document>() {
        {
            setDelimiter(",");
            setFieldExtractor(new BeanWrapperFieldExtractor<Document>() {
                {
                    setNames(new String[] { "docID", "docName", "docPath" });
                }
            });
        }
    });
    return writer;
}

读取过程-写入步骤:

@Bean
public Step step(StepBuilderFactory stepBuilderFactory,
                 MongoItemReader<Document> reader,
                 Processors processors,
                 FlatFileItemWriter<Document> writer
) {
    return stepBuilderFactory
            .get("MainStep").<Document, Document>chunk(100)
            .reader(reader)
            .processor(processors)
            .writer(writer)
            .build();
}

作业的定义应该包括第一步阅读(step 1)

@Bean
public Job job(JobBuilderFactory jobBuilderFactory,
               Step readMongoFirstTime,
               Step step) {
    return jobBuilderFactory
            .get(appName)
            .start(readMongoFirstTime)
            .next(readProcessWriteStep)
            .next(emailStep)
            .build();
}

根据第一步需要读取的数据量,可以通过作业执行上下文将第一步的信息传递到第二步。但是,如果数据太多,你应该小心。

最后一步需要发送电子邮件。另一件需要注意的事情是创建的文件占用的内存量。