ElasticSearch的查詢(二)
一、Query String search
新增測試資料
PUT test_search { "mappings": { "test_type": { "properties": { "dname": { "type": "text", "analyzer": "standard" }, "ename": { "type": "text", "analyzer": "standard" }, "eage": { "type": "long" }, "hiredate": { "type": "date" }, "gender": { "type": "keyword" } } } } } POST test_search/test_type/_bulk {"index":{}} {"dname":"Sales Department","ename":"張三","eage":20,"hiredate":"2019-01-01","gender":"男性"} {"index":{}} {"dname":"Sales Department","ename":"李四","eage":21,"hiredate":"2019-02-01","gender":"男性"} {"index":{}} {"dname":"Development Department","ename":"王五","eage":23,"hiredate":"2019-01-03","gender":"男性"} {"index":{}} {"dname":"Development Department","ename":"趙六","eage":26,"hiredate":"2018-01-01","gender":"男性"} {"index":{}} {"dname":"Development Department","ename":"韓梅梅","eage":24,"hiredate":"2019-03-01","gender":"女性"} {"index":{}} {"dname":"Development Department","ename":"錢虹","eage":29,"hiredate":"2018-03-01","gender":"女性"}
search的引數都是類似http請求頭中的字串引數提供搜尋條件的
GET [/index_name/type_name/]_search[?parameter_name=parameter_value&...]
1,全搜尋
timeout引數:是超時時長定義。代表每個節點上的每個shard執行搜尋時最多耗時多久。不會影響響應的正常返回。只會影響返回響應中的資料數量。
如:索引a中,有10億資料。儲存在5個shard中,假設每個shard中2億資料,執行全資料搜尋的時候,需要耗時1000毫秒。定義timeout為10毫秒,代表的是shard執行10毫秒,搜尋出多少資料,直接返回。
在商業專案中,是禁止全資料搜尋的。必須指定搜尋的索引,型別和關鍵字。如果沒有指定索引或型別,則代表開發目的不明確,需要重新做用例分析。如果沒有關鍵字,稱為索引內全搜尋,也叫魔鬼搜尋。
GET [索引名/型別名/]_search?timeout=10ms
結果返回:
{ "took": 144, #請求耗時多少毫秒 "timed_out": false, #是否超時。預設情況下沒有超時機制,也就是客戶端等待ElasticSearch搜尋結束(無論執行多久),提供超時機制的話,ElasticSearch則在指定時長內處理搜尋,在指定時長結束的時候,將搜尋的結果直接返回(無論是否搜尋結束)。指定超時的方式是傳遞引數,引數單位是:毫秒-ms。秒-s。分鐘-m。 "_shards": { "total": 1, #請求傳送到多少個shard上 "successful": 1,#成功返回搜尋結果的shard "skipped": 0, #停止服務的shard "failed": 0 #失敗的shard }, "hits": { "total": 1, #返回了多少結果 "max_score": 1, #搜尋結果中,最大的相關度分數,相關度越大分數越高,_score越大,排位越靠前。 "hits": [ #搜尋到的結果集合,預設查詢前10條資料。 { "_index": "test_index", #資料所在索引 "_type": "my_type", #資料所在型別 "_id": "1", #資料的id "_score": 1, #資料的搜尋相關度分數 "_source": { # 資料的具體內容。 "field": "value" } } ] } }
2,multi index搜尋
所謂的multi-index就是從多個index中搜索資料。相對使用較少,只有在複合資料搜尋的時候,可能出現。一般來說,如果真使用複合資料搜尋,都會使用_all。
如:搜尋引擎中的無條件搜尋。(現在的應用中都被遮蔽了。使用的是預設搜尋條件,執行資料搜尋。 如: 電商中的搜尋框預設值, 搜尋引擎中的類別)
無條件搜尋,在搜尋應用中稱為“魔鬼搜尋”,代表的是,搜尋引擎會執行全資料檢索,效率極低,且對資源有非常高的壓力。
GET _search #搜尋所有的索引 GET 索引名1,索引名2/_search # 搜尋多個index中的資料 GET 索引名/型別名/_search # 所屬一個index中type的資料 GET prefix_*/_search # 萬用字元搜尋 GET *_suffix/_search GET 索引名1,索引名2/型別名/_search # 搜尋多個index中type的資料 GET _all/_search # _all代表所有的索引
3,條件搜尋
query string search 搜尋是通過HTTP請求的請求頭傳遞引數的,預設的HTTP請求頭字符集是ISO-8859-1,請求頭傳遞中文會有亂碼。
GET 索引名/_search?q=欄位名:搜尋條件
4,分頁搜尋
預設情況下,ElasticSearch搜尋返回結果是10條資料。從第0條開始查詢
GET 索引名/_search?from=0&size=10 # from 從第幾行開始查詢,行號從0開始。
5,+/-搜尋
語法:
GET 索引名/_search?q=欄位名:條件 #不加+/-預設使用的是+ GET 索引名/_search?q=+欄位名:條件 GET 索引名/_search?q=-欄位名:條件
+ :和不定義符號含義一樣,就是搜尋指定的欄位中包含keywords的資料,預設。
- : 與+符號含義相反,就是搜尋指定的欄位中不包含keywords的資料。
6,排序
GET 索引名/_search?sort=欄位名:排序規則
案例:
GET test_search/_search?sort=eage:asc GET test_search/_search?sort=eage:desc GET test_search/_search?sort=gender:desc,eage:desc
二、DSL
DSL - Domain Specified Language , 特殊領域的語言。
請求引數是請求體傳遞的。在ElasticSearch中,請求體的字符集預設為UTF-8。
語法:
GET 索引名/_search { "command":{ "parameter_name" : "parameter_value"} }
1,查詢所有
GET 索引名/_search { "query" : { "match_all" : {} } }
2,match search
全文檢索。要求查詢條件拆分後的任意詞條與具體資料匹配就算搜尋結果。
GET 索引名/_search { "query": { "match": { "欄位名": "搜尋條件" } } }
3,phrase search
短語檢索。要求查詢條件必須和具體資料完全匹配才算搜尋結果。其特徵是:1-搜尋條件不做任何分詞解析;2-在搜尋欄位對應的倒排索引(正排索引)中進行精確匹配,不再是簡單的全文檢索。
GET 索引名/_search { "query": { "match_phrase": { "欄位名": "搜尋條件" } } }
4,range
範圍檢索
GET 索引名/型別名/_search { "query" : { "range" : { "欄位名" : { "gt" : 搜尋條件1, "lte" : 搜尋條件2 } } } }
5,term
片語搜尋。忽略搜尋條件分詞,在ElasticSearch倒排索引中進行精確匹配。
GET 索引名/型別名/_search { "query" : { "term" : { "欄位名": "搜尋條件" } } } GET 索引名/型別名/_search { "query" : { "terms" : { "欄位名": ["搜尋條件1", "搜尋條件2"] } } }
- term是將傳入的文字原封不動地(不分詞)拿去查詢。
- match會對輸入進行分詞處理後再去查詢,部分命中的結果也會按照評分由高到低顯示出來。
- match_phrase是按短語查詢,只有存在這個短語的文件才會被顯示出來。會對傳入的文字進行分詞,但是必須完全匹配並且順序相同。
6,多條件must、should、must_not
- must陣列中的多個條件必須同時滿足
- must_not陣列中的多個條件必須都不滿足
- should陣列中的多個條件有任意一個滿足即可。
GET 索引名/型別名/_search { "query": { "bool": { "must": [ #陣列中的多個條件必須同時滿足 { "range": { "欄位名": { "lt": 條件 } } } ], "must_not":[ #陣列中的多個條件必須都不滿足 { "match": { "欄位名": "條件" } }, { "range": { "欄位名": { "gte": "搜尋條件" } } } ], "should": [# 陣列中的多個條件有任意一個滿足即可。 { "match": { "欄位名": "條件" } }, { "range": { "欄位名": { "gte": "搜尋條件" } } } ] } } }
7,排序
在ElasticSearch的搜尋中,預設是使用相關度分數實現排序的。可以通過搜尋語法實現定製化排序。
GET 索引名/型別名/_search { "query": { [搜尋條件] }, "sort": [ { "欄位名1": { "order": "asc" } }, { "欄位名2": { "order": "desc" } } ] }
注意:在ElasticSearch中,如果使用text型別的欄位作為排序依據,會有問題。ElasticSearch需要對text型別欄位資料做分詞處理。如果使用text型別欄位做排序,ElasticSearch給出的排序結果未必友好,畢竟分詞後,先使用哪一個單詞做排序都是不合理的。所以ElasticSearch中預設情況下不允許使用text型別的欄位做排序,如果需要使用字串做結果排序,則可使用keyword型別欄位作為排序依據,因為keyword欄位不做分詞處理。
8,分頁
DSL分頁也是使用from和size實現的。
GET 索引名稱/_search { "query":{ "match_all":{} }, "from": 起始下標, "size": 查詢記錄數 }
9,高亮
在搜尋中,經常需要對搜尋關鍵字做高亮顯示,這個時候就可以使用highlight語法。
GET 索引名/_search { "query": { "match": { "欄位名": "條件" } }, "highlight": { "fields": { "要高亮顯示的欄位名": { "fragment_size": 5, #每個分段長度,預設20 "number_of_fragments": 1 #返回多少個分段,預設3 } }, "pre_tags": ["字首"], "post_tags": ["字尾"] } }
案例:
GET test_search/_search { "query": { "bool": { "should": [ { "match": { "dname": "Development department" } }, { "match": { "gender": "男性" } } ] } }, "highlight": { "fields": { "dname": { "fragment_size": 20, "number_of_fragments": 1 }, "gender": { "fragment_size": 20, "number_of_fragments": 1 } }, "pre_tags": [ "<span style='color:red'>" ], "post_tags": [ "</span>" ] }, "from": 2, "size": 2 }
10,聚合查詢
語法:
"aggs": { "NAME": {# 指定結果的名稱 "AGG_TYPE": {# 指定具體的聚合方法, TODO: # 聚合體內製定具體的聚合欄位 } }, "NAME": {# 指定結果的名稱 "AGG_TYPE": {# 指定具體的聚合方法, TODO: # 聚合體內製定具體的聚合欄位 } } }
三、SpringDataElasticsearch
原始碼:cloud-es
1,新增pom檔案
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency>
2,修改applicaiton配置
#低版本使用5.x,注意使用的springdata的版本與es是否對應 spring.data.elasticsearch.cluster-name=es5-cluster spring.data.elasticsearch.cluster-nodes= hadoop208:9300,hadoop209:9300 #高版本使用6.x spring.elasticsearch.rest.uris=http://hadoop208:9200,http://hadoop209:9200
3,建立實體
案例:Item物件
- @Document指定實體類和索引對應關係@Id 指定主鍵
- indexName:索引名稱
- type: 索引型別(不加會給預設,es7之後刪除)
- shards: 主分片數量,預設5
- replicas:複製分片數量,預設1
- @Field指定普通屬性
- type: 對應Elasticsearch中屬性型別。使用FiledType列舉可以快速獲取。測試發現沒有type屬性可能出現無法自動建立型別問題,所以一定要有type屬性。
- text型別能被分詞
- keywords不能被分詞
- index: 是否建立索引。作為搜尋條件時index必須為true
- analyzer:指定分詞器型別。
- fielddata:指定是否為text型別欄位建立正向索引。預設為false,設定為true則可以使用此欄位排序。
4,使用方式
案例:ItemTest
&n