汽車網(wǎng)站建設論壇網(wǎng)絡營銷渠道有哪三類
文章目錄
- 前言
- 一、Elasticsearch DSL Query 的分類
- 二、全文檢索查詢
- 2.1 `match` 查詢
- 2.2 `multi_match` 查詢
- 三、精確查詢
- 3.1 term 查詢
- 3.2 range 查詢
- 四、地理坐標查詢
- 4.1 geo_bounding_box 查詢
- 4.2 geo_distance 查詢
- 五、復合查詢
- 5.1 function score 查詢
- 5.2 boolean 查詢
- 六、對搜索結果的處理
- 6.1 對搜索結果進行排序
- 6.2 對搜索結果進行分頁
- 6.3 對搜索結果中的搜索關鍵字高亮處理
前言
Elasticsearch(簡稱ES)是一個強大的開源搜索和分析引擎,廣泛應用于各種應用程序中,從企業(yè)級搜索引擎到日志和指標分析。其強大之處在于其靈活的數(shù)據(jù)模型和豐富的查詢語言,使得用戶能夠輕松地進行全文檢索、精確查詢、地理坐標查詢等操作。
本文將深入探討Elasticsearch的DSL(Domain Specific Language)查詢,分為多個部分進行介紹。首先,我們會了解Elasticsearch DSL Query的分類,然后深入研究全文檢索查詢、精確查詢、地理坐標查詢以及復合查詢等不同類型的查詢。
每一節(jié)都會提供詳細的語法和實際示例,以便讀者能夠更好地理解和運用Elasticsearch中強大的查詢功能。最后,我們將介紹對搜索結果進行排序、分頁以及搜索關鍵字高亮處理等實用的處理技巧,以完善搜索體驗。
讓我們開始深入探討Elasticsearch DSL Query,發(fā)現(xiàn)如何利用其強大的功能來提升搜索和分析的效果。
一、Elasticsearch DSL Query 的分類
Elasticsearch 提供了強大而靈活的DSL(領域特定語言)查詢,用于定義對索引庫中文檔的不同類型查詢。下面將詳細介紹一些常見的 DSL查詢類型:
1. 查詢所有 - match_all
查詢所有文檔,通常用于測試或獲取整個索引的文檔。
{"query": {"match_all": {}}
}
2. 全文檢索查詢
match
查詢
利用分詞器對用戶輸入的內(nèi)容進行分詞,然后在索引中匹配分詞后的詞語。
{"query": {"match": {"field_name": "search_text"}}
}
multi_match
查詢
在多個字段上執(zhí)行全文檢索查詢。
{"query": {"multi_match": {"query": "search_text","fields": ["field1", "field2"]}}
}
3. 精確查詢
ids
查詢
根據(jù)文檔ID查詢文檔。
{"query": {"ids": {"values": ["doc_id1", "doc_id2"]}}
}
term
查詢
根據(jù)精確詞條值查找數(shù)據(jù),適用于 keyword、數(shù)值、日期、boolean等類型字段。
{"query": {"term": {"field_name": "exact_value"}}
}
range
查詢
根據(jù)范圍查詢,適用于數(shù)值、日期等類型的范圍查詢。
{"query": {"range": {"field_name": {"gte": "start_value","lte": "end_value"}}}
}
4. 地理查詢
geo_distance
查詢
根據(jù)經(jīng)緯度查詢指定距離范圍內(nèi)的文檔。
{"query": {"geo_distance": {"distance": "10km","location": {"lat": 40.73,"lon": -73.98}}}
}
geo_bounding_box
查詢
根據(jù)指定的矩形框查詢文檔。
{"query": {"geo_bounding_box": {"location": {"top_left": {"lat": 40.73,"lon": -74.1},"bottom_right": {"lat": 40.01,"lon": -71.12}}}}
}
5. 復合查詢
bool
查詢
通過組合多個查詢條件,支持must、must_not、should等邏輯。
{"query": {"bool": {"must": [{ "match": { "field1": "value1" } },{ "range": { "field2": { "gte": 10, "lte": 20 } } }],"must_not": [{ "term": { "field3": "value2" } }],"should": [{ "match": { "field4": "value3" } }]}}
}
function_score
查詢
根據(jù)某個函數(shù)計算的分數(shù)對查詢結果進行打分,用于加權不同的查詢條件。
{"query": {"function_score": {"query": { "match": { "field": "search_text" } },"functions": [{"filter": { "range": { "field2": { "gte": 10, "lte": 20 } } },"weight": 2}],"score_mode": "multiply"}}
}
以上是一些常見的 Elasticsearch DSL查詢類型,在使用的時候可以根據(jù)具體需求靈活組合這些查詢條件來實現(xiàn)復雜的搜索和過濾功能。下面是針對于這些不同查詢的詳細說明以及查詢演示。
二、全文檢索查詢
全文檢索查詢是通過對用戶輸入的內(nèi)容進行分詞,然后在索引中匹配分詞后的詞語,實現(xiàn)更靈活的文本搜索。在Elasticsearch中,常用的關鍵詞是 match
和 multi_match
。
2.1 match
查詢
match
查詢會根據(jù)一個字段進行查詢,適用于單一字段的全文檢索。在實際應用中,可以使用 copy_to
將多個字段的值合并到一個字段,從而實現(xiàn)類似 multi_match
的查詢效果。
例如,針對 hotel
索引庫的全文檢索查詢:
GET /hotel/_search
{"query": {"match": {"all": "如家"}}
}
這里假設 all
字段是通過 copy_to
包含了多個字段的內(nèi)容,如:“brand”、“business”、“name”。查詢結果如下:
2.2 multi_match
查詢
multi_match
查詢允許根據(jù)多個字段進行全文檢索查詢,但需要注意,參與查詢的字段越多,查詢效率可能越低。
例如,使用 multi_match
查詢:
GET /hotel/_search
{"query": {"multi_match": {"query": "如家","fields": ["brand", "business", "name"]}}
}
在這個例子中,參與查詢的字段同樣是:“brand”、“business”、 “name”。查詢結果如下:
可以觀察到,match
和 multi_match
的查詢結果是相同的。在實際應用中,選擇使用哪種方式要根據(jù)具體需求和性能考慮來決定。
三、精確查詢
精確查詢是搜索引擎中常用的查詢方式,特別適用于針對關鍵字、數(shù)值、日期、boolean等類型字段的精準檢索。在酒店訂購網(wǎng)站等應用中,用戶通常希望根據(jù)特定的條件,如城市、星級、品牌、價格范圍等,進行準確的信息檢索。
下面將介紹在 Elasticsearch 中如何使用 term
和 range
進行精確查詢。
3.1 term 查詢
term
查詢用于根據(jù)詞條的精確值進行查詢。例如,在酒店訂購網(wǎng)站中,用戶希望查找位于上海的所有酒店,可以使用以下 DSL 語句:
GET /hotel/_search
{"query": {"term": {"city": {"value": "上海"}}}
}
查詢結果:
上述查詢返回了所有城市為上海的酒店信息。然而,要注意的是,term
查詢對查詢關鍵字的精確匹配要求較高。如果將查詢的值更改為 “上海北京”,將找不到匹配的結果:
因此,在使用 term
查詢時,務必確保查詢的關鍵字是準確的。
3.2 range 查詢
range
查詢用于根據(jù)值的范圍進行查詢,特別適用于數(shù)值型字段,比如價格范圍。例如,用戶希望查找價格在 100 到 200 之間的酒店,可以使用以下 DSL 語句:
GET /hotel/_search
{"query": {"range": {"price": {"gte": 100,"lte": 200}}}
}
查詢結果:
在上述查詢中,使用了 gte
表示大于等于某個值,而 lte
表示小于等于某個值。通過這樣的查詢,可以精確地獲取符合價格范圍的酒店信息。
總的來說,精確查詢在搜索引擎中是非常常用且實用的功能,通過合理使用 term
和 range
查詢,可以滿足用戶對于準確信息檢索的需求。
四、地理坐標查詢
地理坐標查詢是 Elasticsearch 中常見的功能之一,特別適用于需要根據(jù)地理位置信息進行搜索的場景,如查詢附近的酒店、出租車、或者附近的人。下面介紹兩種常用的地理坐標查詢方式:geo_bounding_box
和 geo_distance
。
4.1 geo_bounding_box 查詢
geo_bounding_box
查詢用于查詢 geo_point
值在某個矩形范圍內(nèi)的所有文檔。以下是一個示例:
GET /indexName/_search
{"query": {"geo_bounding_box": {"FIELD": {"top_left": {"lat": 31.1,"lon": 121.5},"bottom_right": {"lat": 30.9,"lon": 121.7}}}}
}
在這個例子中,通過指定矩形的左上角和右下角的經(jīng)緯度,可以查詢所有位置在這個矩形范圍內(nèi)的文檔。
搜索范圍示意圖,形狀為矩形:
4.2 geo_distance 查詢
geo_distance
查詢用于查詢到指定中心點距離小于某個距離值的所有文檔。以下是一個示例:
GET /indexName/_search
{"query": {"geo_distance": {"distance": "15km","FIELD": "31.21,121.5"}}
}
在這個例子中,通過指定中心點的經(jīng)緯度和距離值,可以查詢所有距離中心點小于 15 公里的文檔。
搜索范圍示意圖,形狀為圓:
通過這兩種方式,可以在地理坐標信息中實現(xiàn)靈活而精確的查詢,滿足用戶在不同應用場景下的位置搜索需求。
五、復合查詢
復合(compound)查詢可以將其它簡單查詢組合起來,實現(xiàn)更復雜的搜索邏輯,例如:
-
function score
: 算分函數(shù)查詢,可以控制文檔相關性算分,控制文檔排名,類似于百度搜索結果中一些頂置的廣告。 -
Boolean Query
:布爾查詢,一個或多個查詢子句的組合,子查詢的組合方式有:- must:必須匹配每個子查詢,類似“與”。
- should:選擇性匹配子查詢,類似“或”。
- must_not:必須不匹配,不參與算分,類似“非”。
- filter:必須匹配,不參與算分。
5.1 function score 查詢
假設,現(xiàn)在文檔中有一些是廣告,我們希望這些廣告在查詢結果中是最靠前的,因此可以使用 function score
查詢來修改特定文檔的打分,例如,給“如家”這個品牌的酒店排名靠前一定:
為了實現(xiàn)這個目標,我們需要提供以下三個要素:
-
哪些文檔需要算分加權?
- 品牌為如家的酒店。
-
算分函數(shù)是什么?
weight
。
-
加權模式是什么?
- 乘積。
查詢 DSL 語句如下:
GET /hotel/_search
{"query": {"function_score": {"query": {"match": {"all": "上海"}},"functions": [{"filter": {"term": {"brand": "如家"}},"weight": 10}],"boost_mode": "multiply"}}
}
說明:
query
:原始查詢條件,搜索文檔并根據(jù)相關性打分(query score)。filter
:過濾條件,符合條件的文檔才會被重新算分。weight
:算分函數(shù),算分函數(shù)的結果稱為 function score ,將來會與 query score 運算,得到新算分。常見的算分函數(shù)有:weight
:給一個常量值,作為函數(shù)結果(function score)。field_value_factor
:用文檔中的某個字段值作為函數(shù)結果。random_score
:隨機生成一個值,作為函數(shù)結果。script_score
:自定義計算公式,公式結果作為函數(shù)結果。
boost_mode
:加權模式,定義 function score 與 query score 的運算方式,包括:multiply
:兩者相乘。默認就是這個。replace
:用 function score 替換 query score。- 其它:
sum
、avg
、max
、min
。
查詢結果:
5.2 boolean 查詢
例如,現(xiàn)在有一個查詢需求:搜索名字包含“如家”,價格不高于400,在坐標31.21,121.5
周圍 10km 范圍內(nèi)的酒店。
GET /hotel/_search
{"query": {"bool": {"must": [{"match": {"name": "如家"}}],"must_not": [{"range": {"price": {"gte": 400}}}],"filter": [{"geo_distance": {"distance": "10km","location": {"lat": 31.21,"lon": 121.5}}}]}}
}
說明:
must
:必須匹配每個子查詢,類似“與”。must_not
:必須不匹配,不參與算分,類似“非”。filter
:必須匹配,不參與算分。
搜索結果:
通過這個例子,我們可以看到如何使用布爾查詢來組合多個條件,實現(xiàn)更精確的搜索。
六、對搜索結果的處理
6.1 對搜索結果進行排序
ElasticSearch 支持對搜索結果排序,默認是根據(jù)相關度算分(_score)來排序。可以排序字段類型有:keyword 類型、數(shù)值類型、地理坐標類型、日期類型等。
示例一:對酒店數(shù)據(jù)按照用戶評價降序排序,評價相同的按照價格升序排序
評價是 score
字段,價格是 price
字段,按照順序添加兩個排序規(guī)則即可。
GET /hotel/_search
{"query": {"match_all": {}},"sort": [{"score": "desc"},{"price": "asc"}]
}
示例二:實現(xiàn)對酒店數(shù)據(jù)按照到(121.507712,31.224612)的位置坐標的距離升序排序
獲取經(jīng)緯度的方式:https://lbs.amap.com/demo/jsapi-v2/example/map/click-to-get-lnglat/。
GET /hotel/_search
{"query": {"match_all": {}},"sort": [{"_geo_distance": {"location": {"lat": 31.224612,"lon": 121.507712},"order": "asc","unit": "km"}}]
}
6.2 對搜索結果進行分頁
ElasticSearch 默認情況下只返回 top 10 的數(shù)據(jù)。而如果要查詢更多數(shù)據(jù)就需要修改分頁參數(shù)了。ElasticSearch 中通過修改 from
、size
參數(shù)來控制要返回的分頁結果。
基本語法如下:
GET /hotel/_search
{"query": {"match_all": {}},"from": 990, // 分頁開始的位置,默認為0"size": 10, // 期望獲取的文檔總數(shù)"sort": [{"price": "asc"}]
}
示例:使用 match_all
查詢,然后對結果進行分頁
GET /hotel/_search
{"query": {"match_all": {}},"from": 0,"size": 5
}
搜索結果,現(xiàn)在就只展示5條結果了:
深度分頁問題:
ES是分布式的,所以會面臨深度分頁問題。例如按 price 排序后,獲取 from = 990,size =10 的數(shù)據(jù):
- 首先在每個數(shù)據(jù)分片上都排序并查詢前1000條文檔。
- 然后將所有節(jié)點的結果聚合,在內(nèi)存中重新排序選出前1000條文檔。
- 最后從這1000條中,選取從990開始的10條文檔。
如果搜索頁數(shù)過深,或者結果集(from + size)越大,對內(nèi)存和 CPU 的消耗也越高。因此 ES 設定結果集查詢的上限是10000。
深度分頁解決方案:
針對深度分頁,ES提供了兩種解決方案:
- **search after:**分頁時需要排序,原理是從上一次的排序值開始,查詢下一頁數(shù)據(jù)。官方推薦使用的方式。
- **scroll:**原理將排序數(shù)據(jù)形成快照,保存在內(nèi)存。官方已經(jīng)不推薦使用。
6.3 對搜索結果中的搜索關鍵字高亮處理
高亮處理,就是在搜索結果中把搜索關鍵字突出顯示。
原理:
- 將搜索結果中的關鍵字用標簽標記出來。
- 在頁面中給標簽添加 CSS 樣式。
語法:
GET /hotel/_search
{"query": {"match": {"FIELD": "TEXT"}},"highlight": {"fields": {"FIELD": {"pre_tags": "<em>", // 用來標記高亮字段的前置標簽"post_tags": "</em>" // 用來標記高亮字段的后置標簽}}}
}
示例:對搜索的品牌名稱進行高亮處理
GET /hotel/_search
{"query": {"match": {"brand": "如家"}},"highlight": {"fields": {"brand": {"pre_tags": "<em>","post_tags": "</em>"}}}
}
搜索結果:
以上便是對ElasticSearch搜索結果進行排序、分頁和關鍵字高亮處理的一些示例和基本操作。