繁体   English   中英

批量索引/用 elasticsearch 为 python 创建文档

[英]Bulk index / create documents with elasticsearch for python

我正在使用 python 生成大量具有随机内容的 elasticsearch 文档,并使用 elasticsearch -py 对它们进行索引。

简化的工作示例(只有一个字段的文档):

from elasticsearch import Elasticsearch
from random import getrandbits

es_client = Elasticsearch('https://elastic.host:9200')

for i in range(1,10000000):
    document = {'my_field': getrandbits(64)}
    es_client.index(index='my_index', document=document)

由于这对每个文档发出一个请求,我尝试通过使用_bulk API 发送 1000 个文档的块来加快它的速度。但是,到目前为止我的尝试没有成功。

我从文档中了解到,您可以将可迭代对象传递给bulk() ,所以我尝试了:

from elasticsearch import Elasticsearch
from random import getrandbits

es_client = Elasticsearch('https://elastic.host:9200')

document_list = []
for i in range(1,10000000):
    document = {'my_field': getrandbits(64)}
    document_list.append(document)
    if i % 1000 == 0:
        es_client.bulk(operations=document_list, index='my_index')
        document_list = []

但这导致

elasticsearch.BadRequestError: BadRequestError(400, 'illegal_argument_exception', '格式错误的操作/元数据行 [1],应为 START_OBJECT 或 END_OBJECT 但已找到 [VALUE_STRING]')

好的,我似乎混淆了两个不同的函数: helpers.bulk()Elasticsearch.bulk() 两者都可以用来实现我打算做的事情,但它们的签名略有不同。

helpers.bulk() function 采用Elasticsearch() object 和一个包含文档作为参数的可迭代对象。 该操作可以指定为_op_type并且可以是indexcreatedeleteupdate之一。 由于_op_type默认为index ,我们可以省略它并在这种情况下简单地传递文档列表:

from elasticsearch import Elasticsearch, helpers
from random import getrandbits

es_client = Elasticsearch('https://elastic.host:9200')

document_list = []
for i in range(1,10000000):
    document = {'my_field': getrandbits(64)}
    document_list.append(document)
    if i % 1000 == 0:
        helpers.bulk(es_client, document_list, index='my_index')
        document_list = []

这很好用。

Elasticsearch.bulk() function 可以替代使用,但动作/操作是强制性的,作为此处可迭代的一部分,语法略有不同。 这意味着我们需要有一个指定操作(在本例中"index": {} )以及每个文档的正文的dict ,而不仅仅是包含文档内容的dict 另请参阅_bulk文档

from elasticsearch import Elasticsearch
from random import getrandbits

es_client = Elasticsearch('https://elastic.host:9200')

actions_list = []
for i in range(1,10000000):
    document = {'my_field': getrandbits(64)}
    actions_list.append({"index": {}, "doc": document})
    if i % 1000 == 0:
        es_client.bulk(operations=actions_list, index='my_index')
        actions_list = []

这也很好用。

我假设以上两个在内部生成相同的_bulk REST API 语句,所以它们最终应该是等价的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM