如何计算元数据并将其添加到现有 Elasticsearch 索引?

How do I compute and add meta data to an existing Elasticsearch index?

我将超过 3800 万个文档(文本字符串)加载到本地计算机上的 Elasticsearch 索引中。我想计算每个字符串的长度并将该值作为元数据添加到索引中。

我是否应该在将文档加载到 Elasticsearch 之前计算字符串长度作为元数据?或者,我可以在事后用计算值更新元数据吗?

我对 Elasticsearch/Kibana 比较陌生,这些问题的出现是由于以下 Python 实验:

  1. 作为字符串列表的数据

     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' 占用了大量内存。

  2. 作为 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 plugin,它将源文档的大小存储在_size字段。

如果您只想存储源文档的特定字段的大小,那么您需要进行不同的操作。

我的建议是创建一个 ingest pipeline 来在每个文档被索引之前对其进行处理。然后可以在第一次索引文档时或加载文档后使用该摄取管道。我会告诉你怎么做。

首先,使用 script processor 创建摄取管道,它将在另一个名为 textLength.

的字段中的 text 字段中存储字符串的大小
PUT _ingest/pipeline/string-length
{
  "description": "My optional pipeline description",
  "processors": [
    {
      "script": {
        "source": "ctx.textLength = ctx.text.length()"
      }
    }
  ]
}

所以,如果您已经将文档加载到 Elasticsearch 中,并且想用每个文档的其中一个字段的长度来丰富每个文档,您可以在事后使用 Update by Query API ,像这样:

POST myindex/_update_by_query?pipeline=string-length&wait_for_completion=false

当文档第一次被索引时,也可以在索引时利用该摄取管道,只需在索引查询中引用该管道,如下所示:

PUT myindex/_doc/123?pipeline=string-length

这两个选项都可以,请尝试一下并选择最适合您需要的选项。