簡體   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