一、前言
小編最近在做到一個檢索相關的需求,要求按照一個欄位的每個字母或者數字進行檢索,如果是不設定分詞規則的話,英文是按照單詞來進行分詞的,
小編以7.6.0版本做的功能哈,大家可以根據自己的版本去官網看看,應該區別不大
例子:
C6153PE-冬日戀歌,要可以通過任何一個數字和字母進行檢索到,并且不區分大小寫,c,6,c6等等!
今天官網上有一些例子,覺得和實戰還是有點區別,小編這里通過了測驗抓緊來記錄一下,希望幫助后來人哈!
二、測驗分詞策略
我們進入官網找到我們需要的策略:
Elasticsearch策略官網
N-gram 分詞器
每當遇到指定字串列中的一個時,ngram標記器首先將文本分解為單詞,然后發出 指定長度的每個單詞的N-gram,
N-gram 就像一個在單詞上移動的滑動視窗——一個指定長度的連續字符序列,它們對于查詢不使用空格或復合詞長的語言很有用,
我們去kibana進行測驗分詞策略是否符合我們的要求:
POST _analyze
{
"tokenizer": "ngram",
"text": "C6153PE-冬日戀歌"
}
分詞分得細,會導致檢索的效率降低,但是需求如此,沒辦法,最重要的是小編這里的資料量只有1w,其實換了這種分詞,是無感知的!

分詞策略規則:
ngram分詞器接受以下引數:
| 引數 | 解釋 |
|---|---|
| min_gram | 以 gram 為單位的最小長度,默認為1. |
| max_gram | 以 gram 為單位的最大字符長度,默認為2. |
| token_chars | 應包含在令牌中的字符類,Elasticsearch 將根據不屬于指定類的字符進行拆分,默認為[](保留所有字符)詳細引數見下表 |
| custom_token_chars | 應被視為令牌一部分的自定義字符,例如,將此設定為+-_將使標記器將加號、減號和下劃線符號視為標記的一部分, |
min_gram將和設定max_gram為相同的值通常是有意義的,長度越小,匹配的檔案越多,但匹配的質量越低,長度越長,匹配越具體,三元組(長度3)是一個很好的起點,官方比較推薦使用3,可能是因為效率分詞粒度兩不誤吧,這里不符合小編的,小編這里使用是1,2,也就是默認的值
| token_chars引數 | 解釋例子 |
|---|---|
| letter | 字母,例如a, b,?或京 |
| digit | 數字,例如3或7 |
| whitespace | 空白,例如" "或"\n" |
| punctuation | 標點,例如!或" |
| symbol | 標記, 例如$或√ |
| custom | 自定義,需要使用 custom_token_chars設定設定的自定義字符 |
custom_token_chars:
應被視為令牌一部分的自定義字符,例如,將此設定為+-_將使標記器將加號、減號和下劃線符號視為標記的一部分,
三、在索引欄位中使用
官方是使用一個欄位進行測驗的,這里小編就直接使用公司的索引進行演示了!
這里是官網的例子:

下面放出來小編實戰后的例子:
總結就是在settings配置分詞策略,在mappings中進行使用即可!!
PUT /product
{
"settings": {
"number_of_shards": 1,
"number_of_replicas": 0,
"index": {
"max_result_window": 100000000
},
# 這里使用分詞策略
"analysis": {
"analyzer": {
"my_analyzer": {
# 這里分詞指定下面策略的具體配置的名稱
"tokenizer": "my_tokenizer",
# 這里忽略大小寫配置
"filter": [
"lowercase"
]
}
},
# 具體策略配置
"tokenizer": {
"my_tokenizer": {
"type": "ngram",
"min_gram": 1,
"max_gram": 2,
"token_chars": [
"letter",
"digit"
]
}
}
}
},
"mappings": {
"dynamic": "strict",
"properties": {
"@timestamp": {
"type": "date"
},
"@version": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"cargoNo": {
"type": "text"
},
"name": {
"type": "text"
},
"sort": {
"type": "integer"
},
"attribute13": {
"type": "text",
# 在需要的欄位指定我們寫的分詞策略
"analyzer": "my_analyzer"
},
"isDeleted": {
"type": "integer"
}
}
}
}
四、在springboot中實戰
為了公司,小編只粘貼部分條件構建規則:
SearchRequest searchRequest = new SearchRequest("product");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
BoolQueryBuilder bool = new BoolQueryBuilder();
BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
boolQueryBuilder.should(QueryBuilders.matchPhraseQuery("name", model))
.should(QueryBuilders.matchPhraseQuery("cargoNo", model))
.should(QueryBuilders.wildcardQuery("cargoNo", "*" + model + "*"))
// 我們分詞規則的欄位查詢
.should(QueryBuilders.matchPhraseQuery("attribute13", model));
bool.must(boolQueryBuilder);
searchSourceBuilder.query(bool);
searchRequest.source(searchSourceBuilder);
我們拿著頁面感受一下分詞帶來的效果:
效果實作,隨便一個字母都可以查詢出來,這里只顯示名稱和一個數字,其實是使用attribute13來進行查詢的,是因為attribute13是名稱的第一個-之前的截出來的,

五、總結
這樣我們就完成了一些定制化的需求,完美交差,還得是看官網啊!!一定要去看官網!搜了好多都沒有這種的教程,寫出來幫助后來人,但是詳細的還得是看官網哈!小編這里也是把官網的一些概念寫到了博客里!!
如果對你有幫助還請不要吝嗇你的發財小手給小編來個一鍵三連哦!謝謝大家了!!
有緣人才可以看得到的哦!!!
點擊訪問!小編自己的網站,里面也是有很多好的文章哦!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/508157.html
標籤:其他
