使用PyE的块中的弹性搜索批量索引

时间:2012-01-25 12:47:28

标签: python csv elasticsearch

我有一个简单的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会表现得更好。

有更有效的方法吗? sleep()延迟会有帮助吗?或者是否有一种简单的方法可以通过编程方式将csv分解为更小的块?

感谢。

3 个答案:

答案 0 :(得分:5)

您可以在创建ES实例时调整批量大小。像这样:

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

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

我不确定在每个第N个文档手动刷新索引是否是最好的选择。默认情况下,Elasticsearch会自动执行此操作。你能做的就是增加那个时间。像这样:

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

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

此处有更多详情: http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-update-settings.html

请注意,清爽是非常昂贵的,根据我的经验,你最好还是: - 让Elastisearch在后台进行刷新 - 在完成插入整批文档后,完全禁用刷新并重新启用它

答案 1 :(得分:3)

每运行第N次

es.refresh()

示例here

答案 2 :(得分:1)

对于将来的访问者,Elasticsearch-py在一次通话中支持bulk operations。请注意,每个文档中的_op_type字段确定发生了哪些操作(如果不存在,则默认为index

E.g。

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)