ES(ElasticSearch)分散式全文搜尋引擎介紹及使用方式
阿新 • • 發佈:2018-12-19
1.什麼是ES
**ES** 全稱 **ElasticSearch** 是一種分散式全文搜尋引擎,基於Lucene(全文搜尋框架)開發而來。
Lucene是公認的迄今為止的最好用的搜尋引擎庫,但是他所提供的API對於我們使用者來說,是非常苦惱的,常要花費大量時間去熟悉學習。ES的出現就很好的解決了這個問題,良好的封裝,易用的API,鏈式書寫方式,開瓶即飲。
2.ES特點
**ES** 雖然是以Lucene核心庫開發的,但是卻不是以它作為核心,**ES** 的貼點體現在: *分散式實時檔案儲存,每個欄位皆能索引* *叢集,可擴充套件(理論上無上限)* *高度整合的服務(RESTful風格的API,各語言客戶端)* *易學易用,開瓶即飲*
3.ES安裝
3.1下載
[ES官方下載地址:](https://www.elastic.co/downloads/elasticsearch)
ES安裝環境只依賴JDK,以5.2.2版本為例,下載對應的檔案即可
3.2安裝
將壓縮包解壓,然後在解壓後的目錄下找到*bin*資料夾,點選名為**elasticsearch.bat** 檔案執行。 測試是否安裝成功:訪問:http://localhost:9200/ ![安裝成功:](https://img-blog.csdnimg.cn/2018110517350745.png) **注意**: 如果本機記憶體過小,或者磁碟空間不足會啟動失敗,手動修改*config*資料夾下**jvm.options**檔案中的引數。 開啟**jvm.options**檔案,搜尋-Xms,得到結果如下:
################################################################ ## IMPORTANT: JVM heap size ################################################################ ## ## You should always set the min and max JVM heap ## size to the same value. For example, to set ## the heap to 4 GB, set: ## ## -Xms4g ## -Xmx4g ## ## See https://www.elastic.co/guide/en/elasticsearch/reference/current/heap-size.html ## for more information ## ################################################################ # Xms represents the initial size of total heap space # Xmx represents the maximum size of total heap space # '#'代表的是註釋, -Xms 最小佔用記憶體 -Xm最大佔用記憶體 如果修改,預設啟動時為2gb 這裡可以修改一下 -Xms200m -Xmx200m
輔助管理工具Kibana5
這裡介紹一款輔助學習工具,避免了使用cmd的尷尬場景
[Kibana5.2.2下載地址:](https://www.elastic.co/downloads/kibana)
- 解壓並編輯config/kibana.yml,設定elasticsearch.url 的值為已啟動的ES
- 啟動Kibana5 : bin\kibana.bat
- 選單: Discover:視覺化查詢分析器 Visualize:統計分析圖表 Dashboard:自定義主面板(新增圖表) Timelion:Timelion是一個kibana時間序列展示元件(暫時不用) Dev Tools :Console(同CURL/POSTER,操作ES程式碼工具,程式碼提示,很方便) Management:管理索引庫(index)、已儲存的搜尋和視覺化結果(save objects)、設定 kibana 伺服器屬性
ES使用
ES資料管理
ES文件
ES是面向文件(document oriented)的,這意味著它可以儲存整個物件或文件(document)。然而它不僅僅是儲存,還會索引(index)每個文件的內容使之可以被搜尋。在ES中,你可以對文件(而非成行成列的資料)進行索引、搜尋、排序、過濾。
ES使用Javascript物件符號(JavaScript Object Notation),也就是JSON,作為文件序列化格式。JSON現在已經被大多語言所支援,而且已經成為NoSQL領域的標準格式。
ES儲存的一個員工文件的格式示例:
{
_index : “crm”,
_type : “user”,就
_id : 1,
_source : {
"email": "[email protected]",
"name": "倪先華",
"info": {
"addr": "四川省成都市",
"age": 30,
"interests": [ "美食", "美女" ]
},
"join_date": "2016-06-01"
}
}
儘管原始的 employee物件很複雜,但它的結構和物件的含義已經被完整的體現在JSON中了,在ES中將物件轉化為JSON並做索引要比在表結構中做相同的事情簡單的多。
文件的必須三個節點:
- _index : “crm”, 文件儲存位置(索引)
- _type : “user”,文件對映型別
- _id : 1,文件唯一標識(可以自定義也可以自動生成)
ES文件的CRUD
以員工物件為例,,類比傳統的資料庫來看:
- 關係資料庫(MYSQL) -> 資料庫DB-> 表TABLE-> 行ROW-> 列Column
- Elasticsearch -> 索引庫Indices -> 型別Types -> 文件Documents -> 欄位Fields
ES叢集可以包含多個索引(indices)(資料庫),每一個索引庫中可以包含多個型別(types)(表),每一個型別包含多個文件(documents)(行),然後每個文件包含多個欄位(Fields)(列)。
//這裡使用Kibana5編寫的
# 建立crm
PUT crm
# 儲存資料
POST crm/user/1
{
"age" : 1,
"name": "fq"
}
# 取值 (_source檢視源資料)
GET crm/user/1
//展示結果
{
"_index": "crm",
"_type": "user",
"_id": "1",
"_version": 3,
"found": true,
"_source": {
"age": 1,
"name": "fq"
}
}
/*
這個API 似乎 允許你修改文件的區域性,但事實上Elasticsearch
遵循與之前所說完全相同的過程,這個過程如下:
1. 從舊文件中檢索JSON
2. 修改它
3. 刪除舊文件
4. 索引新文件
*/
# 存在修改,不存在建立(先刪除在建立)
POST crm/user/1
{
"age" : 2,
"name": "fqq"
}
# 取值(_source只看源資料)
GET crm/user/1/_source
//展示結果
{
"age": 2,
"name": "fqq"
}
# 刪除文件
DELETE crm/user/1
//查詢會查詢不到,沒有結果返回
# 獲取所有文件
GET _search
# 分頁查詢
/*
和SQL使用 LIMIT 關鍵字返回只有一頁的結果一樣,Elasticsearch接受 from 和 size 引數:
size : 每頁條數,預設 10
from : 跳過開始的結果數,預設 0
*/
GET _search?size=5&from=10
DSL查詢與過濾
概念
由ES提供豐富且靈活的查詢語言叫做DSL查詢(Query DSL),它允許你構建更加複雜、強大的查詢。
DSL(Domain Specific Language特定領域語言)以JSON請求體的形式出現。
//查詢字串模式:同樣是使用Kibana5
GET itsource/employee/_search?q=fullName:倪先華
DSL模式:
GET itsource/employee/_search
{
"query" : {
"match" : {
"fullName" : "倪先華"
}
}
}
DSL查詢
使用DSL查詢,必須要傳遞query引數給ES。
GET _search
{"query": YOUR_QUERY_HERE}
# 例項一個完整查詢
/*
查詢公司員工性別為女的員工,並按照加入時間降序、年齡升序排列,最終返回第21條至30條資料(只返回名字、年齡和email欄位)
*/
GET itsource/employee/_search
{
"query": {
"match": {"sex":"女"}
},
"from": 20,
"size": 10,
" _source": ["fullName", "age", "email"],
"sort": [{"join_date": "desc"},{"age": "asc"}]
}
DSL過濾
DSL過濾語句和DSL查詢語句非常相似,但是它們的使用目的卻不同: DSL過濾查詢文件的方式更像是對於我的條件“有”或者“沒有”,而DSL查詢語句則像是“有多像”。 DSL過濾和DSL查詢在效能上的區別:
- 過濾結果可以快取並應用到後續請求。
- 查詢語句同時匹配文件,計算相關性,所以更耗時,且不快取。
- 過濾語句可有效地配合查詢語句完成文件過濾。
原則上,使用DSL查詢做全文字搜尋或其他需要進行相關性評分的場景,其它全用DSL過濾
使用方式
{
"query": {
"bool": {
# 必須條件
"must": [
{"match": {"description": "search" }}
],
# 過濾條件
"filter": {
"term": {"tags": "lucene"}
}
}
}
}
//① 全匹配(match_all)
//普通搜尋(匹配所有文件):
{
"query" : {
"match_all" : {}
}
}
//如果需要使用過濾條件(在所有文件中過濾,紅色部分預設可不寫):
{
"query" : {
"bool" : {
"must" : [{
"match_all":{}
}],
"filter":{....}
}
}
}
/*② 標準查詢(match和multi_match)
match查詢是一個標準查詢,不管你需要全文字查詢還是精確查詢基本上都要用到它。
如果你使用match查詢一個全文字欄位,它會在真正查詢之前用分析器先分析查詢字元:*/
{
"query": {
"match": {
"fullName": "Steven King"
}
}
}
//上面的搜尋會對Steven King分詞,並找到包含Steven或King的文件,然後給出排序分值。
//如果用 match 下指定了一個確切值,在遇到數字,日期,布林值或者 not_analyzed的字串時,它將為你搜索你給定的值,如:
{ "match": { "age": 26 }}
{ "match": { "date": "2014-09-01" }}
{ "match": { "public": true }}
{ "match": { "tag": "full_text" }}
//multi_match 查詢允許你做 match查詢的基礎上同時搜尋多個欄位:
{
"query":{
"multi_match": {
"query": "Steven King",
"fields": [ "fullName", "title" ]
}
}
}
/*上面的搜尋同時在fullName和title欄位中匹配。
提示:match一般只用於全文欄位的匹配與查詢,一般不用於過濾。*/
//③單詞搜尋與過濾(Term和Terms)
{
"query": {
"bool": {
"must": {
"match_all": {}
},
"filter": {
"term": {
"tags": "elasticsearch"
}
}
}
}
}
//Terms搜尋與過濾
{
"query": {
"terms": {
"tags": ["jvm", "hadoop", "lucene"],
"minimum_match": 2
}
}
}
//minimum_match:至少匹配個數,預設為1
/*④ 組合條件搜尋與過濾(Bool)
組合搜尋bool可以組合多個查詢條件為一個查詢物件,查詢條件包括must、should和must_not。
例如:查詢愛好有美女,同時也有喜歡遊戲或運動,且出生於1990-06-30及之後的人。*/
{
"query": {
"bool": {
"must": [{"term": {"hobby": "美女"}}],
"should": [{"term": {"hobby": "遊戲"}},{"term": {"hobby": "運動"}}],
"must_not": [{"range" :{"birth_date":{"lt": "1990-06-30"}}} ],
"filter": [...],
"minimum_should_match": 1
}
}
}
//提示: 如果 bool 查詢下沒有must子句,那至少應該有一個should子句。但是 如果有 must子句,那麼沒有 should子句也可以進行查詢。
/*
⑤ 範圍查詢與過濾(range)
range過濾允許我們按照指定範圍查詢一批資料:*/
{
"query":{
"range": {
"age": {
"gte": 20,
"lt": 30
}
}
}
}
//上例中查詢年齡大於等於20並且小於30。
//gt:> gte:>= lt:< lte:<=
/*⑥ 存在和缺失過濾器(exists和missing)*/
{
"query": {
"bool": {
"must": [{
"match_all": {}
}],
"filter": {
"exists": { "field": "gps" }
}
}
}
}
/*提示:exists和missing只能用於過濾結果。
⑦ 前匹配搜尋與過濾(prefix)
和term查詢相似,前匹配搜尋不是精確匹配,而是類似於SQL中的like ‘key%’*/
{
"query": {
"prefix": {
"fullName": "倪"
}
}
}
//上例即查詢姓倪的所有人。
/*⑧ 萬用字元搜尋(wildcard)
使用*代表0~N個,使用?代表1個。*/
{
"query": {
"wildcard": {
"fullName": "倪*華"
}
}
}