1 Elasticsearch概述
1.1 認(rèn)識(shí)ES
Elasticsearch是一個(gè)基于Lucene庫(kù)的搜索引擎。它提供了一個(gè)分布式、支持多租戶的全文搜索引擎,可以快速地儲(chǔ)存、搜索和分析海量數(shù)據(jù)??梢杂糜谒阉鞲鞣N文檔并支持多租戶。Elasticsearch至少需要Java 8。
1.2應(yīng)用場(chǎng)景
在線網(wǎng)上商店,允許客戶搜索您銷售的產(chǎn)品。在這種情況下,可以使用Elasticsearch存儲(chǔ)整個(gè)產(chǎn)品目錄和庫(kù)存,并為它們提供搜索和自動(dòng)填充建議。
收集日志或交易數(shù)據(jù),并分析和挖掘此數(shù)據(jù)以查找趨勢(shì),統(tǒng)計(jì)信息,摘要或異常。在這種情況下,您可以使用Logstash來(lái)收集,聚合和解析數(shù)據(jù),然后讓Logstash將此數(shù)據(jù)提供給Elasticsearch。一旦數(shù)據(jù)在Elasticsearch中,您就可以運(yùn)行搜索和聚合來(lái)挖掘您感興趣的任何信息。
價(jià)格警報(bào)平臺(tái),允許精通價(jià)格的客戶指定一條規(guī)則,例如“我有興趣購(gòu)買特定的電子產(chǎn)品,如果小工具的價(jià)格在下個(gè)月內(nèi)從任何供應(yīng)商降至X美元以下,我希望收到通知” 。在這種情況下,您可以刮取供應(yīng)商價(jià)格,將其推入Elasticsearch并使用其反向搜索功能來(lái)匹配價(jià)格變動(dòng)與客戶查詢,并最終在發(fā)現(xiàn)匹配后將警報(bào)推送給客戶。
1.3重要概念
集群Cluster:集群是一個(gè)或多個(gè)節(jié)點(diǎn)的集合,它們共同保存您的整個(gè)數(shù)據(jù),并提供跨所有節(jié)點(diǎn)的聯(lián)合索引和搜索功能。
節(jié)點(diǎn)Node:節(jié)點(diǎn)是作為集群一部分的單個(gè)服務(wù)器,存儲(chǔ)數(shù)據(jù)并參與群集的索引和搜索功能。
索引Index:索引是具有某些類似特征的文檔集合。索引由名稱標(biāo)識(shí),必須全部小寫,此名稱用于在對(duì)其中的文檔執(zhí)行索引,搜索,更新和刪除操作時(shí)引用索引。
文檔Document:文檔是可以編制索引的基本信息單元。Index 里面單條的記錄稱為 Document。
分片和副本:索引可能存儲(chǔ)大量可能超過(guò)單個(gè)節(jié)點(diǎn)的硬件限制的數(shù)據(jù)。為了解決這個(gè)問(wèn)題,Elasticsearch提供了將索引細(xì)分為多個(gè)稱為分片的功能。
1.4核心模塊
analysis:主要負(fù)責(zé)詞法分析及語(yǔ)言處理,也就是我們常說(shuō)的分詞,通過(guò)該模塊可最終形成存儲(chǔ)或者搜索的最小單元 Term。
index 模塊:主要負(fù)責(zé)索引的創(chuàng)建工作。
store 模塊:主要負(fù)責(zé)索引的讀寫,主要是對(duì)文件的一些操作,其主要目的是抽象出和平臺(tái)文件系統(tǒng)無(wú)關(guān)的存儲(chǔ)。
queryParser 模塊:主要負(fù)責(zé)語(yǔ)法分析,把我們的查詢語(yǔ)句生成 Lucene 底層可以識(shí)別的條件。
search 模塊:主要負(fù)責(zé)對(duì)索引的搜索工作。
similarity 模塊:主要負(fù)責(zé)相關(guān)性打分和排序的實(shí)現(xiàn)。
1.5檢索方式
單個(gè)詞查詢:指對(duì)一個(gè) Term 進(jìn)行查詢。比如若要查找包含字符串“Lucene”的文檔,則只需在詞典中找到 Term“Lucene”,再獲得在倒排表中對(duì)應(yīng)的文檔鏈表即可。
AND:指對(duì)多個(gè)集合求交集。比如若要查找既包含字符串Lucene又包含字符串Solr的文檔,則查找步驟如下:在詞典中找到 Term Lucene得到Lucene對(duì)應(yīng)的文檔鏈表。在詞典中找到 TermSolr,得到Solr對(duì)應(yīng)的文檔鏈表。合并鏈表,對(duì)兩個(gè)文檔鏈表做交集運(yùn)算。
OR:指多個(gè)集合求并集。比如,若要查找包含字符串Luence或者包含字符串Solr的文檔,則查找步驟如下同上,對(duì)兩個(gè)文檔鏈表做并集運(yùn)算,合并后的結(jié)果包含Lucene或者包含Solr。
NOT:指對(duì)多個(gè)集合求差集。比如若要查找包含字符串Solr但不包含字符串Lucene的文檔,則查找步驟如下同上,對(duì)兩個(gè)文檔鏈表做差集運(yùn)算,用包含Solr的文檔集減去包含Lucene的文檔集,運(yùn)算后的結(jié)果就是包含Solr但不包含Lucene。
2 ES特性與優(yōu)缺點(diǎn)
2.1 ES特性
Elasticsearch可擴(kuò)展高達(dá)PB級(jí)的結(jié)構(gòu)化和非結(jié)構(gòu)化數(shù)據(jù)。
Elasticsearch可以用來(lái)替代MongoDB等做文檔存儲(chǔ)。
Elasticsearch使用非標(biāo)準(zhǔn)化來(lái)提高搜索性能。
Elasticsearch是受歡迎的企業(yè)搜索引擎之一,目前使用如Wikipedia,GitHub等。
Elasticsearch是開(kāi)放源代碼,可在Apache許可證版本2.0下提供。
2.2ES優(yōu)點(diǎn)
Elasticsearch是基于Java開(kāi)發(fā)的,這使得它在幾乎每個(gè)平臺(tái)上都兼容。
Elasticsearch是實(shí)時(shí)的。
Elasticsearch是分布式的,這使得它易于在任何大型組織中擴(kuò)展和集成。
與Apache Solr相比,在Elasticsearch中處理多租戶非常容易。
Elasticsearch使用JSON對(duì)象作為響應(yīng)。
Elasticsearch支持幾乎大部分文檔類型,但不支持文本呈現(xiàn)的文檔類型。
2.3ES缺點(diǎn)
Elasticsearch在處理請(qǐng)求和響應(yīng)數(shù)據(jù)方面沒(méi)有多語(yǔ)言和數(shù)據(jù)格式支持(僅在JSON中可用),與Apache Solr不同不可以使用CSV,XML等格式。
Elasticsearch也有一些傷腦的問(wèn)題發(fā)生,雖然在極少數(shù)情況下才會(huì)發(fā)生。
3 ES安裝部署
本文主要采用Win10下的Elasticsearch安裝,當(dāng)然Linux安裝操作起來(lái)更加簡(jiǎn)便了。完成之后對(duì)python安裝elasticsearch包,并實(shí)現(xiàn)交互案例。
?第一步:條件檢查
Elasticsearch至少需要Java 8,首先需要java -version查看當(dāng)前版本。
?第二步:安裝ES
這里采用elasticsearch-7.1.0-windows-x86_64下載地址鏈接: https://pan.baidu.com/s/1k5AOGpMy8uJEXtA6KoNb7g 提取碼: qtmj 。
★bin :運(yùn)行Elasticsearch實(shí)例和插件管理所需的腳本
★confg: 配置文件所在的目錄
★lib : Elasticsearch使用的庫(kù)
★data : Elasticsearch使用的所有數(shù)據(jù)的存儲(chǔ)位置
★logs : 關(guān)于事件和錯(cuò)誤記錄的文件
★plugins: 存儲(chǔ)所安裝插件的地方,比如中文分詞工具
然后去運(yùn)行 bin/elasticsearch(Mac 或 Linux)或者 binelasticsearch.bat (Windows) 即可啟動(dòng) Elasticsearch 了。我們啟動(dòng)后發(fā)現(xiàn)網(wǎng)頁(yè)并不現(xiàn)實(shí)信息,測(cè)試下本地網(wǎng)絡(luò)是否聯(lián)通:
發(fā)現(xiàn)是一般性故障,查詢資料顯示由于防火墻的問(wèn)題,經(jīng)過(guò)測(cè)試關(guān)閉”公用網(wǎng)絡(luò)防火墻“即可:
后我們?cè)偃?a href="http://www.ttokpm.com/tags/pi/" target="_blank">ping下本地IP:
這時(shí)已經(jīng)顯示ping通狀態(tài),再次啟動(dòng)binelasticsearch.bat (Windows),打開(kāi)http://localhost:9200/顯示如下表示成功安裝ES。
?第三步:Python安裝ES
下載地址是https://www.elastic.co/downloads/elasticsearch。如果在windows下安排部署參考文章http://www.cnblogs.com/viaiu/p/5715200.html。如果是Python開(kāi)發(fā)可以使用pip install elasticsearch安裝。
4 ES構(gòu)建全文搜索
4.1插入數(shù)據(jù)
打開(kāi)python運(yùn)行環(huán)境,首先導(dǎo)入【from elasticsearch import Elasticsearch】,然后編寫插入數(shù)據(jù)的方法:
# 插入數(shù)據(jù) def InsertDatas(): # 默認(rèn)host為localhost,port為9200.但也可以指定host與port es = Elasticsearch() es.create(index="my_index",doc_type="test_type",id=11,ignore=[400,409],body={"name":"python","addr":'四川省'}) # 查詢結(jié)果 result = es.get(index="my_index",doc_type="test_type",id=11) print('單條數(shù)據(jù)插入完成: ',result)
實(shí)例化Elasticsearch,其中默認(rèn)為空即host為localhost,port為9200。為空也可以指定網(wǎng)絡(luò)IP與端口。通過(guò)創(chuàng)建索引index和文檔類別doc_type,文檔id,body為插入數(shù)據(jù)的內(nèi)容,其中ES支持的數(shù)據(jù)僅為JSON類型,ignore=409忽略異常。運(yùn)行結(jié)果如下:
4.2批量插入數(shù)據(jù)
上面案例我們插入一條信息,查詢顯示一系列參數(shù)包括索引、文檔類型、文檔ID唯一標(biāo)識(shí),版本號(hào)等。其中資源中包含數(shù)據(jù)信息,如果我們想插入多條信息可以參考以下代碼:
# 批量插入數(shù)據(jù) def AddDatas(): es = Elasticsearch() datas = [{ 'name': '美國(guó)留給伊拉克的是個(gè)爛攤子', 'addr': 'http://view.news.qq.com/zt2011/usa_iraq/index.htm' },{ "name":"python", "addr":'四川省' }] for i,data in enumerate(datas): es.create(index="my_index",doc_type="test_type", id=i,ignore=[400,409],body=data) # 查詢結(jié)果 result = es.get(index="my_index",doc_type="test_type",id=0) print(' 批量插入數(shù)據(jù)完成: ',result['_source'])
我們將數(shù)據(jù)放在datas列表中,如果我們數(shù)據(jù)在一個(gè)json文件中存儲(chǔ),也可以通過(guò)讀取文本信息并保存在datas中,之后對(duì)其進(jìn)行插入即可。這里面文件ID我采用枚舉的序號(hào),也可以采用隨機(jī)數(shù)或者指定格式。完成所有插入之后我們選擇第一條id=0的信息查詢,此處查詢與上文不同,我們只看文章內(nèi)容可以采用result['_source']方法,結(jié)果如下:
4.3更新數(shù)據(jù)
如果我們插入數(shù)據(jù)信息有問(wèn)題,我們想去修正??梢圆捎胾pdate方法,這里面與我們接觸的MySQL,MongoDB等SQL語(yǔ)句差不多。唯一注意的是我們更新數(shù)據(jù)時(shí)候采用{"doc":{"name":"python1","addr":"深圳1"}}字典模式,尤其是doc標(biāo)識(shí)不能忘記,代碼實(shí)現(xiàn)如下:
# 3 更新數(shù)據(jù) def UpdateDatas(): es = Elasticsearch() es.update(index="my_index",doc_type="test_type",id=11,ignore=[400,409],body={"doc":{"name":"python1","addr":"深圳1"}}) # 更新結(jié)果 result = es.get(index="my_index",doc_type="test_type",id=11) print(' 數(shù)據(jù)id=11更新完成: ',result['_source']['name'])
這里我們假如只想查詢更新后信息的name字段,可以采用source后面加['name']方法,為什么這么設(shè)置呢?請(qǐng)參看插入數(shù)據(jù)運(yùn)行結(jié)果分析。
4.4 刪除數(shù)據(jù)
這里面比較簡(jiǎn)單,我們指定文檔的索引、文檔類型和文檔ID即可。
# 刪除數(shù)據(jù) def DeleteDatas(): es = Elasticsearch() result = es.delete(index='my_index',doc_type='test_type',id=11) print(' 數(shù)據(jù)id=11刪除完成: ')
4.5條件查詢數(shù)據(jù)
我們通過(guò)插入數(shù)據(jù)構(gòu)建一個(gè)簡(jiǎn)單我數(shù)據(jù)信息,如果我們想獲取索引中的所有文檔可以采用{"query":{"match_all":{}}}條件查詢,這里面指定關(guān)注的是使用的search方法,上文查詢數(shù)據(jù)采用get方法,其實(shí)兩者都是可以作為查詢使用的。代碼如下:
# 條件查詢 def ParaSearch(): es = Elasticsearch() query1 = es.search(index="my_index", body={"query":{"match_all":{}}}) print(' 查詢所有文檔 ',query1) query2 = es.search(index="my_index", body={"query":{"term":{'name':'python'}}}) print(' 查找名字Python的文檔: ',query2['hits']['hits'][0])
我們獲取索引所有文檔的信息
獲取文檔中name為Python的信息
-
搜索引擎
+關(guān)注
關(guān)注
0文章
114瀏覽量
13340 -
Elasticsearch
+關(guān)注
關(guān)注
0文章
26瀏覽量
2813
原文標(biāo)題:Python 和 Elasticsearch 構(gòu)建簡(jiǎn)易搜索
文章出處:【微信號(hào):datathinks,微信公眾號(hào):datathinks】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論