我使用lambda将上传到S3的PDF文件推送到带有ES摄取附件插件的AWS托管弹性搜索。
有些PDF可能很大 - 超过100mb - 似乎最好以块的形式传输文件,而不是将整个文件缓冲区加载到lambda内存中。 s3-lambda-es示例代码我已经看到了json日志的所有工作都很容易流,但我还没有看到任何人使用二进制文件来获取摄取插件。
注意:我使用带有http-aws-es connectionClass的elasticssearch-js库使其与lambda一起使用。
我当前的代码基本上有效,但它在发送到ES之前加载了整个pdf。 这是getObject回调:
s3.getObject({ Bucket: bucket, Key: key }, function(err, data) {
if (err) {
console.log(err, err.stack); // an error occurred
context.fail();
} else {
console.log('data: ', data); // successful response
var attachment = data.Body.toString('base64');
elasticsearch.index(
{
index: 'attachments2',
pipeline: 'pdf_attachment2',
type: 'pdf',
body: {
data: attachment
}
},
function(error, resp) {
if (error) {
console.trace('index error!', error);
} else {
console.log('index response', resp);
context.succeed();
}
}
);
}
});
有没有更好的方法将单个大型文档流式传输到ES?
答案 0 :(得分:0)
有没有更好的方法将单个大型文档流式传输到ES?
简答:不,请使用s3.getObject
答案很长:是的,请参阅下面的
首先,限制是Elasticsearch。它根本不暴露任何流API。如果你尝试search API docs,你甚至都不会发现任何流。
为什么呢?因为Elasticsearch不是为将大文件流式传输而设计的!
请求正文的默认限制为100MB,can be increased to 2GB with tuning。 (相同的链接解释了为什么你不应该索引这样的大文件)。简而言之,你会遇到坏事。不相关的搜索结果,超载ES,吃掉所有RAM等等。
此外,您提到您将使用ingest attachment plugin,如果您继续default configuration,您可能会发现默认值为indexed_chars
:
这意味着,ES默认阻止您存储大于100KB的字段!
当然,您可以覆盖所有内容,并根据需要调整ES,并将2GB文档存储在1个字段中。但一般不建议这样做。
建议的方法是将较大的pdf拆分为较小的块,并将它们编入具有相同documentId
或其他内容的单独文档。然后,您可以使用ES fields collapsing通过共享documentId
对文档进行重复数据删除(ES 5.3中的新功能,在旧版本中使用热门命中聚合)。那就是你不会最终在你的Lambda中发送100MB。
总而言之:您无法为1个文档流式传输ES大文本,ES不是为此而设计的。但如果您愿意,可以发送100MB文本。 AWS Lambda应该没问题,内存将在需要时处理。
答案 1 :(得分:-1)
@bscandanavia请分享您用于创建管道的方法和代码。我无法弄清楚如何使用ES摄取附件插件。
很抱歉将其发布为答案,因为我无法添加评论