1、資料準備
首先建立book索引
PUT /book/
{
"settings": {
"number_of_shards": 1,
"number_of_replicas": 0
},
"mappings": {
"properties": {
"name": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart"
},
"description": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart"
},
"studymodel": {
"type": "keyword"
},
"price": {
"type": "double"
},
"timestamp": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
},
"pic": {
"type": "text",
"index": false
}
}
}
}
插入資料
PUT /book/_doc/1
{
"name": "Bootstrap開發",
"description": "Bootstrap是一個非常流行的開發框架。此開發框架可以幫助不擅長css頁面開發的程式人員輕鬆的實現一個css,不受瀏覽器限制的精美介面css效果。",
"studymodel": "201002",
"price": 38.6,
"timestamp": "2019-08-25 19:11:35",
"pic": "group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg",
"tags": [
"bootstrap",
"dev"
]
}
PUT /book/_doc/2
{
"name": "java程式設計思想",
"description": "java語言是世界第一程式語言,在軟體開發領域使用人數最多。",
"studymodel": "201001",
"price": 68.6,
"timestamp": "2019-08-25 19:11:35",
"pic": "group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg",
"tags": [
"java",
"dev"
]
}
PUT /book/_doc/3
{
"name": "spring開發基礎",
"description": "spring 在java領域非常流行,java程式設計師都在用。",
"studymodel": "201001",
"price": 88.6,
"timestamp": "2019-08-24 19:11:35",
"pic": "group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg",
"tags": [
"spring",
"java"
]
}
2、Filter與Query示例
需求:使用者查詢description中有"java程式設計師",並且價格大於80小於90的資料。
2.1 Query
首先採用Query來進行查詢,首先查詢description中有"java程式設計師"。
GET /book/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"description": "java程式設計師"
}
}
]
}
}
}
查詢結果如下:
可以看到,查詢出來兩條資料,score分別是1.9、0.5。
然後查詢description中有"java程式設計師",並且價格大於80小於90的資料
GET /book/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"description": "java程式設計師"
}
},
{
"range": {
"price": {
"gte": 80,
"lte": 90
}
}
}
]
}
}
}
再次檢視結果:
這次查詢出來一條資料,score變為2.9。這一條資料在上一次的查詢結果中的score為1.9。然後接著往下看使用Filter。
2.2 filter
還是相同的需求,首先查詢description中有"java程式設計師"。
GET /book/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"description": "java程式設計師"
}
}
]
}
}
}
查詢結果如下:
通過查詢結果可以看到,查詢的兩條資料的score是1.9、0.5。
然後使用filter查詢description中有"java程式設計師",並且價格大於80小於90的資料
GET /book/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"description": "java程式設計師"
}
}
],
"filter": {
"range": {
"price": {
"gte": 80,
"lte": 90
}
}
}
}
}
}
查詢結果如下:
可以看到,查詢出來的資料與使用query查詢結果一樣,但是score依舊為1.9。
說明在使用query查詢的過程中,影響到了相關度(score)的排序,在使用filter進行查詢,並不會影響相關度(score)的計算。
2.3 filter與query對比
filter,僅僅只是按照搜尋條件過濾出需要的資料而已,不計算任何相關度分數,對相關度沒有任何影響。
query,會去計算每個document相對於搜尋條件的相關度,並按照相關度進行排序。
應用場景:
一般來說,如果你是在進行搜尋,需要將最匹配搜尋條件的資料先返回,那麼用query。如果你只是要根據一些條件篩選出一部分資料,不關注其排序,那麼用filter。
2.4 filter與query效能
filter,不需要計算相關度分數,不需要按照相關度分數進行排序,同時還有內建的自動cache最常使用filter的資料。比如在範圍查詢,keyword欄位查詢中推薦使用filter來進行查詢。
query,相反,要計算相關度分數,按照分數進行排序,而且無法cache結果。
在同等查詢結果下,filter的效能一般是要優於query的。
3、explain分析語法
在實際的應用過程中,需要查詢的邏輯一般比較複雜,那當語句冗長的時候,這時候顯然不太可能通過直接執行語句來除錯語法正確與否,這個時候就可以通過explain來驗證語句的正確性。
驗證錯誤語句:
GET /book/_validate/query?explain
{
"query": {
"mach": {
"description": "java程式設計師"
}
}
}
返回結果如下,錯誤資訊為沒有名叫mach的query。
{
"valid" : false,
"error" : "org.elasticsearch.common.ParsingException: no [query] registered for [mach]"
}
再來看語句正確的情況下
GET /book/_validate/query?explain
{
"query": {
"match": {
"description": "java程式設計師"
}
}
}
返回,返回結果還包含對語句的解釋:從description查詢java關鍵詞,從description查詢程式設計師關鍵詞。
{
"_shards" : {
"total" : 1,
"successful" : 1,
"failed" : 0
},
"valid" : true,
"explanations" : [
{
"index" : "book",
"valid" : true,
"explanation" : "description:java description:程式設計師"
}
]
}
應用場景:
一般用在那種特別複雜龐大的搜尋下,比如你一下子寫了上百行的搜尋,這個時候可以先用validate api去驗證一下,搜尋是否合法。合法以後,explain就像mysql的執行計劃,可以看到搜尋的目標等資訊。