我有一个.json.gz
文件,我希望加载到弹性搜索中。
我的第一次尝试是使用json
模块将JSON转换为dicts列表。
import gzip
import json
from pprint import pprint
from elasticsearch import Elasticsearch
nodes_f = gzip.open("nodes.json.gz")
nodes = json.load(nodes_f)
Dict示例:
pprint(nodes[0])
{u'index': 1,
u'point': [508163.122, 195316.627],
u'tax': u'fehwj39099'}
使用Elasticsearch:
es = Elasticsearch()
data = es.bulk(index="index",body=nodes)
然而,这会返回:
elasticsearch.exceptions.RequestError: TransportError(400, u'illegal_argument_exception', u'Malformed action/metadata line [1], expected START_OBJECT or END_OBJECT but found [VALUE_STRING]')
除此之外,我希望能够找到给定tax
查询的point
,以防这对我应该如何使用elasticsearch索引数据产生影响。
答案 0 :(得分:4)
Alfe指出了我正确的方向,但我无法让他的代码发挥作用。
我找到了两个解决方案:
逐行显示for循环:
es = elasticsearch.Elasticsearch()
for node in nodes:
_id = node['index']
es.index(index='nodes',doc_type='external',id=_id,body=node)
批量使用helper
:
actions = [
{
"_index" : "nodes_bulk",
"_type" : "external",
"_id" : str(node['index']),
"_source" : node
}
for node in nodes
]
helpers.bulk(es,actions)
对于22
代码列表,批量增加约343724
倍。
答案 1 :(得分:0)
ES批量库显示了一些问题,包括性能问题,无法设置特定_id
等。但由于ES的批量API不是很复杂,我们自己做了:
import requests
headers = { 'Content-type': 'application/json',
'Accept': 'text/plain'}
jsons = []
for d in docs:
_id = d.pop('_id') # take _id out of dict
jsons.append('{"index":{"_id":"%s"}}\n%s\n' % (_id, json.dumps(d)))
data = ''.join(jsons)
response = requests.post(url, data=data, headers=headers)
我们需要设置一个特定的_id
,但我想您可以跳过此部分,以防您希望ES自动设置随机_id
。
希望有所帮助。
答案 2 :(得分:0)
这是我使用批量api的工作代码:
定义字典列表:
from elasticsearch import Elasticsearch, helpers
es = Elasticsearch([{'host':'localhost', 'port': 9200}])
doc = [{'_id': 1,'price': 10, 'productID' : 'XHDK-A-1293-#fJ3'},
{'_id':2, "price" : 20, "productID" : "KDKE-B-9947-#kL5"},
{'_id':3, "price" : 30, "productID" : "JODL-X-1937-#pV7"},
{'_id':4, "price" : 30, "productID" : "QQPX-R-3956-#aD8"}]
helpers.bulk(es, doc, index='products',doc_type='_doc', request_timeout=200)