我有一个简单的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分解为更小的块?
感谢。
答案 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)
答案 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)