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":"女性"}
View Code
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,//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