公號:碼農充電站pro
主頁:https://codeshellme.github.io
Search APIs 用於搜索和聚合存儲在 ES 中的數據。
1,搜索模板 Template
Search 模板使用 mustache 語言來呈現搜索請求,使得搜索請求參數化,達到開發人員與搜索工程師解耦的效果。
示例:
# 定義一個搜索模板
POST _scripts/template_name # 模板名稱爲 template_name
{
"script": { # 固定寫法
"lang": "mustache", # 固定寫法
"source": { # 固定寫法
"_source": ["title", "overview"], # 返回哪些字段
"size": 20,
"query": {
"multi_match": {
"query": "{{q}}", # 搜索參數,參數名爲 q
"fields": ["title", "overview"]
}
}
}
}
}
# 使用模板
POST template_name/_search/template
{
"id":"template_name",
"params": { # 填寫參數 q
"q": "basketball with cartoon aliens"
}
}
2,搜索建議 Suggesters
搜索建議幫助用戶在輸入搜索的過程中,進行自動補全或者糾錯,這種功能在 ES 中通過 Suggesters 來完成。
Suggesters 會將輸入的文本分解爲 token,然後在索引的字典裏查找相似的 Term 並返回。
ES 提供了 4 種類別的 Suggesters:
- Term suggester
- Phrase Suggester
- Completion Suggester
- Context Suggester
Suggester Mode 用於指定在什麼情況下給出搜索建議:
- missing:搜索不到內容時,給出搜索建議
- popular:推薦出現頻率更高的詞
- always:無論是否存在,都給出搜索建議
2.1,Term suggester
示例:
DELETE articles
# 插入一些文檔
POST articles/_bulk
{ "index" : { } }
{ "title_completion": "lucene is very cool"}
{ "index" : { } }
{ "title_completion": "Elasticsearch builds on top of lucene"}
{ "index" : { } }
{ "title_completion": "Elasticsearch rocks"}
{ "index" : { } }
{ "title_completion": "elastic is the company behind ELK stack"}
{ "index" : { } }
{ "title_completion": "Elk stack rocks"}
{ "index" : {} }
term-suggestion 搜索:
POST /articles/_search
{
"size": 1,
"query": {
"match": {
"body": "lucen rock" # 查詢字符串,拼寫錯誤
}
},
"suggest": { # 搜索建議
"term-suggestion": { # suggester 名稱,自定義
"text": "lucen rock", # 這裏也是查詢字符串
"term": { # term-suggestion
"suggest_mode": "missing", # 建議模式,在沒有搜索到時,到 body 字段搜索
"field": "body" # 建議字段
}
}
}
}
一些參數:
- sort:排序方法,默認按照評分排序,也可以按照 frequency 排序。
- prefix_length:默認情況下,首字母不一致就不會給出建議詞。如果將其設置爲 0,就會爲 hock 建議 rock。
示例:
POST /articles/_search
{
"suggest": {
"term-suggestion": {
"text": "lucen hocks",
"term": {
"suggest_mode": "always",
"field": "body",
"prefix_length":0,
"sort": "frequency"
}
}
}
}
2.2,Phrase Suggester
Phrase Suggester
在 Term Suggester
的基礎上增加了一些額外的邏輯。
一些參數:
max_errors
:最多可以拼錯的 Terms 數confidence
:限制返回結果數,默認爲 1。值爲 0 的話,表示返回前 N 個結果。
示例:
POST /articles/_search
{
"suggest": {
"my-suggestion": { # 一個 Suggester,自定義名稱
"text": "lucne and elasticsear rock hello world ", # 搜索字符串
"phrase": { # phrase-suggestion
"field": "body",
"max_errors":2,
"confidence":0,
"direct_generator":[{
"field":"body",
"suggest_mode":"always"
}],
"highlight": {
"pre_tag": "<em>",
"post_tag": "</em>"
}
}
}
}
}
2.3,Completion Suggester
Completion Suggester
用於自動補全,用戶每輸入一個字符,就需要即時發送一個查詢請求到後端查找匹配項。
自動補全功能對性能要求比較高, ES 採用了不同的數據結構,而非通過倒排索引來完成。
自動補全功能將分詞數據編碼成 FST,與索引放在一起。FST 會被加載到內存中,以加快速度。FSF 的缺點是隻能用於前綴查找。
示例:
首先,字段的類型必須是 completion,該數據類型用於自動補全功能。
DELETE articles
PUT articles
{
"mappings": {
"properties": {
"title_completion":{
"type": "completion"
}
}
}
}
定義好數據類型之後才能插入數據:
POST articles/_bulk
{ "index" : { } }
{ "title_completion": "lucene is very cool"}
{ "index" : { } }
{ "title_completion": "Elasticsearch builds on top of lucene"}
{ "index" : { } }
{ "title_completion": "Elasticsearch rocks"}
{ "index" : { } }
{ "title_completion": "elastic is the company behind ELK stack"}
{ "index" : { } }
{ "title_completion": "Elk stack rocks"}
{ "index" : {} }
查詢數據:
POST articles/_search?pretty
{
"size": 0,
"suggest": {
"article-suggester": { # 自定義名稱
"prefix": "elk ", # 查詢前綴,基於該前綴進行自動補全
"completion": { # completion
"field": "title_completion" # 字段
}
}
}
}
2.4,Context Suggester
Context Suggester
是對 Completion Suggester
的擴展,稱爲上下文感知推薦,可以在搜索時提供更多的上下文信息。
例如,輸入 "star":
- 咖啡相關:建議 "starbucks"
- 電影相關:建議 "start wars"
可以定義兩種類型的上下文:
- Category:任意字符串
- Geo:地理位置信息
實現 Context Suggester 的步驟:
- 定義一個 Mapping
- 索引數據,並且爲每個文檔加入 Context 信息
- 查詢
示例:
# 設置 Mapping
PUT comments
PUT comments/_mapping
{
"properties": {
"comment_autocomplete":{ # 字段名稱
"type": "completion", # 字段類型
"contexts":[{ # Context Suggester,是一個數組
"type":"category", # 上下文類型
"name":"comment_category" # 名稱
}]
}
}
}
# 寫入數據
POST comments/_doc
{
"comment":"I love the star war movies",
"comment_autocomplete":{
"input":["star wars"], # 如果請求 movies 類型的數據,就返回 "star wars"
"contexts":{
"comment_category":"movies" # 自定義 movies 類型
}
}
}
POST comments/_doc
{
"comment":"Where can I find a Starbucks",
"comment_autocomplete":{
"input":["starbucks"], # 如果請求 coffee 類型的數據,就返回 "starbucks"
"contexts":{
"comment_category":"coffee" # 自定義 coffee 類型
}
}
}
}
# 查詢
POST comments/_search
{
"suggest": {
"MY_SUGGESTION": { # 自定義名稱
"prefix": "sta", # 搜索字符串前綴
"completion":{ # 自動補全,固定寫法
"field":"comment_autocomplete", # 字段名稱
"contexts":{
"comment_category":"coffee" # 請求 coffee 類型的數據
}
}
}
}
}
2.5,幾種建議的指標比較
比較:
- 精準度: Completion > Phrase > Term
- 召回率:Term > Phrase > Completion
- 性能:Completion > Phrase > Term
(本節完。)
推薦閱讀:
歡迎關注作者公衆號,獲取更多技術乾貨。