Elasticsearch使用PyE以块为单位搜索批量索引



我有一个简单的python脚本,用于索引包含100万行的CSV文件:

import csv
from pyes import *
reader = csv.reader(open('data.csv', 'rb'))
conn = ES('127.0.0.1:9200', timeout=20.0)
counter = 0
for row in reader:
        try:
                data = {"name":row[5]}
                conn.index(data,'namesdb',counter, bulk=True)
                counter += 1
        except:
                pass

这很有效,但随着我们进入数千人,一切都呈指数级放缓。

我猜如果我把索引分成小块,ES会表现得更好。

有更有效的方法吗?睡懒觉有帮助吗?或者有没有一种简单的方法可以通过编程将csv分解成更小的块?

谢谢。

您可以在创建ES实例时调整批量大小。类似这样的东西:

conn = ES('127.0.0.1:9200', timeout=20.0, bulk_size=100)

默认的批量大小为400。也就是说,当您批量获得400个文档时,pyes会自动发送批量内容。如果您想在bulk_size到达之前(例如:在退出之前)发送批量,您可以调用conn.flush_bulk(forced=True)

我不确定是否在每N个文档手动刷新索引是最好的选择。Elasticsearch默认情况下每秒都会自动刷新。你能做的就是增加时间。类似这样的东西:

curl -XPUT localhost:9200/namesdb/_settings -d '{
    "index" : {
        "refresh_interval" : "3s"
    }
}'

或者,你可以像德拉甘建议的那样手动刷新,但在这种情况下,通过将间隔设置为"-1"来禁用Elasticsearch的自动刷新可能是有意义的。但您不需要刷新每个X文档,您可以在插入完所有文档后进行刷新。

更多详细信息请点击此处:http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-update-settings.html

请注意,提神是相当昂贵的,根据我的经验,你最好选择其中一种:-让Elastisearch在后台进行刷新-完全禁用刷新,并在我插入完整堆文档后重新启用

每N次计数运行

es.refresh()

此处的示例

对于未来的访问者,Elasticsearch py支持在单个调用中进行批量操作。请注意,每个单据中的_op_type字段决定了发生的操作(如果不存在,则默认为index

例如

import elasticsearch as ES
import elasticsearch.helpers as ESH
es = ES.Elasticsearch()
docs = [ doc1, doc2, doc3 ]
n_success, n_fail = ESH.bulk(es, docs, index='test_index', doc_type='test_doc',
                             stats_only=True)

最新更新