Elasticsearch高级检索之使用单个字母数字进行分词N-gram tokenizer(不区 ...

打印 上一主题 下一主题

主题 558|帖子 558|积分 1674

一、前言

小编最近在做到一个检索相关的需求,要求按照一个字段的每个字母或者数字进行检索,如果是不设置分词规则的话,英文是按照单词来进行分词的。
小编以7.6.0版本做的功能哈,大家可以根据自己的版本去官网看看,应该区别不大
例子:
C6153PE-冬日恋歌,要可以通过任何一个数字和字母进行检索到,并且不区分大小写。c,6,c6等等!
今天官网上有一些例子,觉得和实战还是有点区别,小编这里通过了测试抓紧来记录一下,希望帮助后来人哈!
二、测试分词策略

我们进入官网找到我们需要的策略:
Elasticsearch策略官网
N-gram 分词器
每当遇到指定字符列表中的一个时,ngram标记器首先将文本分解为单词,然后发出 指定长度的每个单词的N-gram。
N-gram 就像一个在单词上移动的滑动窗口——一个指定长度的连续字符序列。它们对于查询不使用空格或复合词长的语言很有用。
我们去kibana进行测试分词策略是否符合我们的要求:
  1. POST _analyze
  2. {
  3.   "tokenizer": "ngram",
  4.   "text": "C6153PE-冬日恋歌"
  5. }
复制代码
分词分得细,会导致检索的效率降低,但是需求如此,没办法,最重要的是小编这里的数据量只有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或7whitespace空白,例如" "或"\n"punctuation标点,例如!或"symbol标记, 例如$或√custom自定义,需要使用 custom_token_chars设置设置的自定义字符custom_token_chars:
应被视为令牌一部分的自定义字符。例如,将此设置为+-_将使标记器将加号、减号和下划线符号视为标记的一部分。
三、在索引字段中使用

官方是使用一个字段进行测试的,这里小编就直接使用公司的索引进行演示了!
这里是官网的例子:

下面放出来小编实战后的例子:
总结就是在settings配置分词策略,在mappings中进行使用即可!!
  1. PUT /product
  2. {
  3.   "settings": {
  4.     "number_of_shards": 1,
  5.     "number_of_replicas": 0,
  6.     "index": {
  7.       "max_result_window": 100000000
  8.     },
  9.     # 这里使用分词策略
  10.     "analysis": {
  11.       "analyzer": {
  12.         "my_analyzer": {
  13.           # 这里分词指定下面策略的具体配置的名称
  14.           "tokenizer": "my_tokenizer",
  15.           # 这里忽略大小写配置
  16.           "filter": [
  17.             "lowercase"
  18.           ]
  19.         }
  20.       },
  21.       # 具体策略配置
  22.       "tokenizer": {
  23.         "my_tokenizer": {
  24.           "type": "ngram",
  25.           "min_gram": 1,
  26.           "max_gram": 2,
  27.           "token_chars": [
  28.             "letter",
  29.             "digit"
  30.           ]
  31.         }
  32.       }
  33.     }
  34.   },
  35.   "mappings": {
  36.     "dynamic": "strict",
  37.     "properties": {
  38.       "@timestamp": {
  39.         "type": "date"
  40.       },
  41.       "@version": {
  42.         "type": "text",
  43.         "fields": {
  44.           "keyword": {
  45.             "type": "keyword",
  46.             "ignore_above": 256
  47.           }
  48.         }
  49.       },
  50.       "cargoNo": {
  51.         "type": "text"
  52.       },
  53.       "name": {
  54.         "type": "text"
  55.       },
  56.       "sort": {
  57.         "type": "integer"
  58.       },
  59.       "attribute13": {
  60.         "type": "text",
  61.         # 在需要的字段指定我们写的分词策略
  62.         "analyzer": "my_analyzer"
  63.       },
  64.       "isDeleted": {
  65.         "type": "integer"
  66.       }
  67.     }
  68.   }
  69. }
复制代码
四、在springboot中实战

为了公司,小编只粘贴部分条件构建规则:
  1. SearchRequest searchRequest = new SearchRequest("product");
  2. SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
  3. BoolQueryBuilder bool = new BoolQueryBuilder();
  4. BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
  5. boolQueryBuilder.should(QueryBuilders.matchPhraseQuery("name", model))
  6.          .should(QueryBuilders.matchPhraseQuery("cargoNo", model))
  7.          .should(QueryBuilders.wildcardQuery("cargoNo", "*" + model + "*"))
  8.          // 我们分词规则的字段查询
  9.          .should(QueryBuilders.matchPhraseQuery("attribute13", model));
  10. bool.must(boolQueryBuilder);
  11. searchSourceBuilder.query(bool);
  12. searchRequest.source(searchSourceBuilder);
复制代码
我们拿着页面感受一下分词带来的效果:
效果实现,随便一个字母都可以查询出来,这里只显示名称和一个数字,其实是使用attribute13来进行查询的,是因为attribute13是名称的第一个-之前的截出来的。

五、总结

这样我们就完成了一些定制化的需求,完美交差,还得是看官网啊!!一定要去看官网!搜了好多都没有这种的教程,写出来帮助后来人,但是详细的还得是看官网哈!小编这里也是把官网的一些概念写到了博客里!!
如果对你有帮助还请不要吝啬你的发财小手给小编来个一键三连哦!谢谢大家了!!
有缘人才可以看得到的哦!!!点击访问!小编自己的网站,里面也是有很多好的文章哦!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

知者何南

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表