上一章節主要介紹了ES的一些重要概念及簡單的CRUD,本章內容將重點介紹ES的多種查詢方式。ES在使用過程中,查詢是最重要的應用場景。
一、Query String Search(‘Query String’方式的搜索)
1.搜索全部商品
GET /shop_index/productInfo/_search
返回結果:
{
"took": 8,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 3,
"max_score": 1,
"hits": [
{
"_index": "shop_index",
"_type": "productInfo",
"_id": "2",
"_score": 1,
"_source": {
"test": "test"
}
},
{
"_index": "shop_index",
"_type": "productInfo",
"_id": "zyWpRGkB8mgaHjxk0Hfo",
"_score": 1,
"_source": {
"name": "HuaWei P20",
"desc": "Expen but easy to use",
"price": 5300,
"producer": "HuaWei Producer",
"tags": [
"Expen",
"Fast"
]
}
},
{
"_index": "shop_index",
"_type": "productInfo",
"_id": "1",
"_score": 1,
"_source": {
"name": "HuaWei Mate8",
"desc": "Cheap and easy to use",
"price": 2500,
"producer": "HuaWei Producer",
"tags": [
"Cheap",
"Fast"
]
}
}
]
}
}
字段解釋:
took:耗費了幾毫秒
timed_out:是否超時,這裏是沒有
_shards:數據被拆到了5個分片上,搜索時使用了5個分片,5個分片都成功地返回了數據,失敗了0個,跳過了0個
hits.total:查詢結果的數量,3個document
max_score:就是document對於一個search的相關度的匹配分數,越相關,就越匹配,分數也越高
hits.hits:包含了匹配搜索的document的詳細數據
2.搜索商品名稱中包含HuaWei的商品,而且按照售價降序排序:
下面這種方法也是"Query String Search"的由來,因爲search參數都是以http請求的query string來附帶的.
GET /shop_index/productInfo/_search?q=name:HuaWei&sort=price:desc
返回結果:
{
"took": 23,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 2,
"max_score": null,
"hits": [
{
"_index": "shop_index",
"_type": "productInfo",
"_id": "zyWpRGkB8mgaHjxk0Hfo",
"_score": null,
"_source": {
"name": "HuaWei P20",
"desc": "Expen but easy to use",
"price": 5300,
"producer": "HuaWei Producer",
"tags": [
"Expen",
"Fast"
]
},
"sort": [
5300
]
},
{
"_index": "shop_index",
"_type": "productInfo",
"_id": "1",
"_score": null,
"_source": {
"name": "HuaWei Mate8",
"desc": "Cheap and easy to use",
"price": 2500,
"producer": "HuaWei Producer",
"tags": [
"Cheap",
"Fast"
]
},
"sort": [
2500
]
}
]
}
}
二、Query DSL(DSL: Domain Specified Language,特定領域的語言)
這種方法是通過一個json格式的http request body請求體作爲條件,可以完成多種複雜的查詢需求,比query string的功能更加強大
1.搜索所有商品
GET /shop_index/productInfo/_search
{
"query": {
"match_all": {}
}
}
返回結果省略...
2.查詢名稱中包含HuaWei的商品,並且按照價格降序排列
GET /shop_index/productInfo/_search
{
"query": {
"match": {
"name": "HuaWei"
}
},
"sort": [
{
"price": {
"order": "desc"
}
}
]
}
返回結果省略...
3.分頁查詢第二頁,每頁1條記錄
GET /shop_index/productInfo/_search
{
"query": {
"match_all": {}
},
"from": 1,
"size": 1
}
返回結果:
{
"took": 6,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 3,
"max_score": 1,
"hits": [
{
"_index": "shop_index",
"_type": "productInfo",
"_id": "zyWpRGkB8mgaHjxk0Hfo",
"_score": 1,
"_source": {
"name": "HuaWei P20",
"desc": "Expen but easy to use",
"price": 5300,
"producer": "HuaWei Producer",
"tags": [
"Expen",
"Fast"
]
}
}
]
}
}
注意:
(1)在實際項目中,如果有條件查詢之後再需要分頁,不需要單獨查詢總條數,ES會返回滿足條件的總條數,可以直接使用;
(2)ES的分頁默認from是從0開始的;
4.只查詢特定字段,比如:name,desc和price字段,其他字段不需要返回
GET /shop_index/productInfo/_search
{
"query": {
"match": {
"name": "HuaWei"
}
},
"_source": ["name","desc","price"]
}
返回結果:
{
"took": 27,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 2,
"max_score": 0.2876821,
"hits": [
{
"_index": "shop_index",
"_type": "productInfo",
"_id": "zyWpRGkB8mgaHjxk0Hfo",
"_score": 0.2876821,
"_source": {
"price": 5300,
"name": "HuaWei P20",
"desc": "Expen but easy to use"
}
},
{
"_index": "shop_index",
"_type": "productInfo",
"_id": "1",
"_score": 0.2876821,
"_source": {
"price": 2500,
"name": "HuaWei Mate8",
"desc": "Cheap and easy to use"
}
}
]
}
}
三.Query Filter(對查詢結果進行過濾)
比如:查詢名稱中包含HuaWei,並且價格大於4000的商品記錄:
GET /shop_index/productInfo/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"name": "HuaWei"
}
}
],
"filter": {
"range": {
"price": {
"gt": 4000
}
}
}
}
}
}
返回結果:
{
"took": 195,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 0.2876821,
"hits": [
{
"_index": "shop_index",
"_type": "productInfo",
"_id": "zyWpRGkB8mgaHjxk0Hfo",
"_score": 0.2876821,
"_source": {
"name": "HuaWei P20",
"desc": "Expen but easy to use",
"price": 5300,
"producer": "HuaWei Producer",
"tags": [
"Expen",
"Fast"
]
}
}
]
}
}
四、全文索引(Full-Text Search)
搜索生產廠商字段中包含"HuaWei MateProducer"的商品記錄:
GET /shop_index/productInfo/_search
{
"query": {
"match": {
"producer": "HuaWei MateProducer"
}
}
}
返回結果:
{
"took": 8,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 4,
"max_score": 0.5753642,
"hits": [
{
"_index": "shop_index",
"_type": "productInfo",
"_id": "SiUBRWkB8mgaHjxkJHyS",
"_score": 0.5753642,
"_source": {
"name": "HuaWei Mate10",
"desc": "Cheap and Beauti",
"price": 2300,
"producer": "HuaWei MateProducer",
"tags": [
"Cheap",
"Beauti"
]
}
},
{
"_index": "shop_index",
"_type": "productInfo",
"_id": "1",
"_score": 0.2876821,
"_source": {
"name": "HuaWei Mate8",
"desc": "Cheap and easy to use",
"price": 2500,
"producer": "HuaWei Producer",
"tags": [
"Cheap",
"Fast"
]
}
},
{
"_index": "shop_index",
"_type": "productInfo",
"_id": "zyWpRGkB8mgaHjxk0Hfo",
"_score": 0.18232156,
"_source": {
"name": "HuaWei P20",
"desc": "Expen but easy to use",
"price": 5300,
"producer": "HuaWei Producer",
"tags": [
"Expen",
"Fast"
]
}
},
{
"_index": "shop_index",
"_type": "productInfo",
"_id": "CSX8RGkB8mgaHjxkV3w1",
"_score": 0.18232156,
"_source": {
"name": "HuaWei nova 4e",
"desc": "cheap and look nice",
"price": 1999,
"producer": "HuaWei Producer",
"tags": [
"Cheap",
"Nice"
]
}
}
]
}
}
從以上結果中可以看到:
id爲"SiUBRWkB8mgaHjxkJHyS"的記錄score分數最高,表示匹配度最高;
原因:
producer分完詞之後包括的詞語有:
(1).HuaWei:
匹配到改詞的記錄ID:'SiUBRWkB8mgaHjxkJHyS','1','CSX8RGkB8mgaHjxkV3w1','zyWpRGkB8mgaHjxk0Hfo'
(2).MateProducer:
匹配到該詞的記錄ID:'SiUBRWkB8mgaHjxkJHyS'
由於"HuaWei MateProducer"兩次匹配到ID爲'SiUBRWkB8mgaHjxkJHyS'的記錄,所以該記錄的score分數最高。
五、Phrase Search(短語搜索)
短語索引和全文索引的區別:
(1)全文匹配:將要搜索的內容分詞,然後挨個單詞去倒排索引中匹配,只要匹配到任意一個單詞,就算是匹配到記錄;
(2)短語索引:輸入的搜索串,必須在指定的字段內容中,完全包含一模一樣的,纔可以算匹配,才能作爲結果返回;
例如:搜索name中包含"HuaWei MateProducer"短語的商品信息:
GET /shop_index/productInfo/_search
{
"query": {
"match_phrase": {
"producer": "HuaWei MateProducer"
}
}
}
返回結果:
{
"took": 158,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 0.5753642,
"hits": [
{
"_index": "shop_index",
"_type": "productInfo",
"_id": "SiUBRWkB8mgaHjxkJHyS",
"_score": 0.5753642,
"_source": {
"name": "HuaWei Mate10",
"desc": "Cheap and Beauti",
"price": 2300,
"producer": "HuaWei MateProducer",
"tags": [
"Cheap",
"Beauti"
]
}
}
]
}
}
可以看到只有包含"HuaWei MateProducer"的記錄才被返回。
六、Highlight Search(搜索高亮顯示)
高亮搜索指的是搜索的結果中,將某些特別需要強調的詞使用特定的樣式展示出來。
例如:搜索商品名稱中包含"Xiao'Mi"的商品,並將搜索的關鍵詞高亮顯示:
GET /shop_index/productInfo/_search
{
"query": {
"match": {
"name": "Xiao'Mi"
}
},
"highlight": {
"fields": {
"name": {}
}
}
}
返回結果:
{
"took": 348,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 0.2876821,
"hits": [
{
"_index": "shop_index",
"_type": "productInfo",
"_id": "HiX9RGkB8mgaHjxk4nxC",
"_score": 0.2876821,
"_source": {
"name": "Xiao'Mi 9",
"desc": "Expen but nice and Beauti",
"price": 3500,
"producer": "XiaoMi Producer",
"tags": [
"Expen",
"Beauti"
]
},
"highlight": {
"name": [
"<em>Xiao'Mi</em> 9"
]
}
}
]
}
}
可以看到,"Xiao'Mi"使用了標籤返回了,可以在HTML中直接以斜體展示。
如果想使用自定義高亮樣式,可以使用pre_tags和post_tags進行自定義,比如:想使用紅色展示,如下所示:
GET /shop_index/productInfo/_search
{
"query": {
"match": {
"name": "Xiao'Mi"
}
},
"highlight": {
"fields": {
"name": {}
},
"pre_tags": [
"<em style='color:red;'>"
],
"post_tags": [
"</em>"
]
}
}
返回結果:
{
"took": 10,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 0.2876821,
"hits": [
{
"_index": "shop_index",
"_type": "productInfo",
"_id": "HiX9RGkB8mgaHjxk4nxC",
"_score": 0.2876821,
"_source": {
"name": "Xiao'Mi 9",
"desc": "Expen but nice and Beauti",
"price": 3500,
"producer": "XiaoMi Producer",
"tags": [
"Expen",
"Beauti"
]
},
"highlight": {
"name": [
"<em style='color:red;'>Xiao'Mi</em> 9"
]
}
}
]
}
}
返回結果中的搜索關鍵字使用表示紅色的css樣式展示出來。
ES的多種搜索方式到此介紹完畢,每種搜索方式中還包含其他的API,文中沒有全部介紹,如果有需要可以自行翻閱官方文檔。歡迎評論轉發!