使用Python操作Elasticsearch數(shù)據(jù)索引的教程
Elasticsearch是一個分布式、Restful的搜索及分析服務(wù)器,Apache Solr一樣,它也是基于Lucence的索引服務(wù)器,但我認(rèn)為Elasticsearch對比Solr的優(yōu)點(diǎn)在于:
- 輕量級:安裝啟動方便,下載文件之后一條命令就可以啟動;
- Schema free:可以向服務(wù)器提交任意結(jié)構(gòu)的JSON對象,Solr中使用schema.xml指定了索引結(jié)構(gòu);
- 多索引文件支持:使用不同的index參數(shù)就能創(chuàng)建另一個索引文件,Solr中需要另行配置;
- 分布式:Solr Cloud的配置比較復(fù)雜。
環(huán)境搭建
啟動Elasticsearch,訪問端口在9200,通過瀏覽器可以查看到返回的JSON數(shù)據(jù),Elasticsearch提交和返回的數(shù)據(jù)格式都是JSON.
>> bin/elasticsearch -f
安裝官方提供的Python API,在OS X上安裝后出現(xiàn)一些Python運(yùn)行錯誤,是因?yàn)閟etuptools版本太舊引起的,刪除重裝后恢復(fù)正常。
>> pip install elasticsearch
索引操作
對于單條索引,可以調(diào)用create或index方法。
from datetime import datetime
from elasticsearch import Elasticsearch
es = Elasticsearch() #create a localhost server connection, or Elasticsearch("ip")
es.create(index="test-index", doc_type="test-type", id=1,
body={"any":"data", "timestamp": datetime.now()})
Elasticsearch批量索引的命令是bulk,目前Python API的文檔示例較少,花了不少時間閱讀源代碼才弄清楚批量索引的提交格式。
from datetime import datetime
from elasticsearch import Elasticsearch
from elasticsearch import helpers
es = Elasticsearch("10.18.13.3")
j = 0
count = int(df[0].count())
actions = []
while (j < count):
action = {
"_index": "tickets-index",
"_type": "tickets",
"_id": j + 1,
"_source": {
"crawaldate":df[0][j],
"flight":df[1][j],
"price":float(df[2][j]),
"discount":float(df[3][j]),
"date":df[4][j],
"takeoff":df[5][j],
"land":df[6][j],
"source":df[7][j],
"timestamp": datetime.now()}
}
actions.append(action)
j += 1
if (len(actions) == 500000):
helpers.bulk(es, actions)
del actions[0:len(actions)]
if (len(actions) > 0):
helpers.bulk(es, actions)
del actions[0:len(actions)]
在這里發(fā)現(xiàn)Python API序列化JSON時對數(shù)據(jù)類型支撐比較有限,原始數(shù)據(jù)使用的NumPy.Int32必須轉(zhuǎn)換為int才能索引。此外,現(xiàn)在的bulk操作默認(rèn)是每次提交500條數(shù)據(jù),我修改為5000甚至50000進(jìn)行測試,會有索引不成功的情況。
#helpers.py source code
def streaming_bulk(client, actions, chunk_size=500, raise_on_error=False,
expand_action_callback=expand_action, **kwargs):
actions = map(expand_action_callback, actions)
# if raise on error is set, we need to collect errors per chunk before raising them
errors = []
while True:
chunk = islice(actions, chunk_size)
bulk_actions = []
for action, data in chunk:
bulk_actions.append(action)
if data is not None:
bulk_actions.append(data)
if not bulk_actions:
return
def bulk(client, actions, stats_only=False, **kwargs):
success, failed = 0, 0
# list of errors to be collected is not stats_only
errors = []
for ok, item in streaming_bulk(client, actions, **kwargs):
# go through request-reponse pairs and detect failures
if not ok:
if not stats_only:
errors.append(item)
failed += 1
else:
success += 1
return success, failed if stats_only else errors
對于索引的批量刪除和更新操作,對應(yīng)的文檔格式如下,更新文檔中的doc節(jié)點(diǎn)是必須的。
{
'_op_type': 'delete',
'_index': 'index-name',
'_type': 'document',
'_id': 42,
}
{
'_op_type': 'update',
'_index': 'index-name',
'_type': 'document',
'_id': 42,
'doc': {'question': 'The life, universe and everything.'}
}
常見錯誤
- SerializationError:JSON數(shù)據(jù)序列化出錯,通常是因?yàn)椴恢С帜硞€節(jié)點(diǎn)值的數(shù)據(jù)類型
- RequestError:提交數(shù)據(jù)格式不正確
- ConflictError:索引ID沖突
- TransportError:連接無法建立
性能

上面是使用MongoDB和Elasticsearch存儲相同數(shù)據(jù)的對比,雖然服務(wù)器和操作方式都不完全相同,但可以看出數(shù)據(jù)庫對批量寫入還是比索引服務(wù)器更具備優(yōu)勢。
Elasticsearch的索引文件是自動分塊,達(dá)到千萬級數(shù)據(jù)對寫入速度也沒有影響。但在達(dá)到磁盤空間上限時,Elasticsearch出現(xiàn)了文件合并錯誤,并且大量丟失數(shù)據(jù)(共丟了100多萬條),停止客戶端寫入后,服務(wù)器也無法自動恢復(fù),必須手動停止。在生產(chǎn)環(huán)境中這點(diǎn)比較致命,尤其是使用非Java客戶端,似乎無法在客戶端獲取到服務(wù)端的Java異常,這使得程序員必須很小心地處理服務(wù)端的返回信息。
相關(guān)文章
python 通過郵件控制實(shí)現(xiàn)遠(yuǎn)程控制電腦操作
這篇文章主要介紹了python 通過郵件控制電腦實(shí)現(xiàn)遠(yuǎn)程控制操作,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-03-03
python如何調(diào)用現(xiàn)有的matlab函數(shù)
這篇文章主要介紹了python如何調(diào)用現(xiàn)有的matlab函數(shù)問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-12-12
NumPy實(shí)現(xiàn)多維數(shù)組中的線性代數(shù)
本文主要介紹了NumPy實(shí)現(xiàn)多維數(shù)組中的線性代數(shù),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-07-07
Python模擬實(shí)現(xiàn)全功能貸款計(jì)算器
在個人理財中,貸款計(jì)算器是一款非常實(shí)用的工具,本文將教你如何使用Python編寫一個全功能的貸款計(jì)算器,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-12-12

