我在本地机器上的Elasticsearch索引中加载了3800多万个文档(文本字符串(。我想计算每个字符串的长度,并将该值作为元数据添加到索引中。
在将文档加载到Elasticsearch之前,我是否应该将字符串长度计算为元数据?或者,我可以在事后用计算值更新元数据吗?
我对Elasticsearch/Kibana比较陌生,这些问题是因为以下Python实验而产生的:
-
作为字符串列表的数据
mylist = ['string_1', 'string_2',..., 'string_N'] L = [len(s) for s in mylist] # this computation takes about 1 minute on my machine
选项1的缺点是我没有利用Elasticsearch,"mylist"占用了大量内存。
-
数据作为Elasticsearch索引,其中"mylist"中的每个字符串都加载到字段"text"中。
from haystack.document_store.elasticsearch import ElasticsearchDocumentStore document_store = ElasticsearchDocumentStore(host='localhost', username='', password='', index='myindex') docs = document_store.get_all_documents_generator() L = [len(d.text) for d in docs] # this computation takes about 6 minutes on my machine
选项2的缺点是计算时间要长得多。好处是generator((释放了内存。计算时间长就是为什么我认为将字符串长度(和其他分析(作为元数据存储在Elasticsearch中是一个很好的解决方案。
我还应该考虑其他选择吗?我错过了什么?
如果您想存储整个文档的大小,我建议安装mapper-size
插件,它将在_size
字段中存储源文档的大小。
如果您只想存储源文档的特定字段的大小,则需要以不同的方式进行操作。
我建议创建一个摄取管道,在每个文档被索引之前处理它。然后,该摄取管道可以在第一次索引文档时使用,也可以在加载文档后使用。我会教你怎么做。
首先,使用script
处理器创建摄取管道,该处理器将在另一个名为textLength
的字段中的text
字段中存储字符串的大小。
PUT _ingest/pipeline/string-length
{
"description": "My optional pipeline description",
"processors": [
{
"script": {
"source": "ctx.textLength = ctx.text.length()"
}
}
]
}
因此,如果您已经将文档加载到Elasticsearch中,并希望用其中一个字段的长度来丰富每个文档,那么您可以在事后使用UpdatebyQueryneneneba API来完成,如下所示:
POST myindex/_update_by_query?pipeline=string-length&wait_for_completion=false
当文档第一次被索引时,也可以在索引时利用摄取管道,只需在索引查询中引用管道,如下所示:
PUT myindex/_doc/123?pipeline=string-length
这两种选择都会奏效,试试看,然后选择最适合你需求的一种。