1 索引的分析

索引分析: 就是把输入的文本块按照一定的策略进行分解, 并建立倒排索引的过程. 在Lucene的架构中, 这个过程由分析器(analyzer)完成.

1.1 分析器的组成

① 字符过滤器(character filter): 比如去除HTML标签、把&替换为and等.

② 分词器(tokenizer): 按照某种规律, 如根据空格、逗号等, 将文本块进行分解.

③ 标记过滤器(token filter): 所有被分词器分解的词都将经过token filters的处理, 它可以修改词(如小写化处理)、去掉词(根据某一规则去掉无意义的词, 如"a", "the", "的"等), 增加词(如同义词"jump"、"leap"等).

注意: 人们一般将分析器通称为分词器, 并不是相等的关系, 而是包含的关系.

1.2 倒排索引的核心原理-normalization

建立倒排索引时, 会执行normalization(正常化)操作 —— 将拆分的各个单词进行处理, 以提高搜索时命中关联的文档的概率.

normalization的方式有: 时态转换, 单复数转换, 同义词转换, 大小写转换等.

比如文档中包含His mom likes small dogs:

① 在建立索引的时候normalization会对文档进行时态、单复数、同义词等方面的处理;

② 然后用户通过近似的mother liked little dog, 也能搜索到相关的文档.

2 ES的默认分词器

(1) ES中的默认分词器: standard tokenizer, 是标准分词器, 它以单词为边界进行分词. 具有如下功能:

① standard token filter: 去掉无意义的标签, 如<>, &, - 等.

② lowercase token filter: 将所有字母转换为小写字母.

③ stop token filer(默认被禁用): 移除停用词, 比如"a"、"the"等.

(2) 测试默认分词器:

GET _analyze			// ES引擎中已有standard分词器, 所以可以不指定index
{
"analyzer": "standard",
"text": "There-is & a DOG<br/> in house"
}

可以发现, Elasticsearch对text文本进行了分析处理, 结果如下:

{
"tokens" : [
{
"token" : "there", // 分词
"start_offset" : 0, // 起始偏移量
"end_offset" : 5, // 结束偏移量
"type" : "<ALPHANUM>", // 分词的类型
"position" : 0 // 该分词在文本中的位置
},
{
"token" : "is",
"start_offset" : 6,
"end_offset" : 8,
"type" : "<ALPHANUM>",
"position" : 1
},
{
"token" : "a",
"start_offset" : 11,
"end_offset" : 12,
"type" : "<ALPHANUM>",
"position" : 2
},
// 省略其他4项
]
}

3 修改分词器

(1) 创建索引后可以添加新的分词器:

说明: 必须先关闭索引, 添加完成后, 再及时打开索引进行搜索等操作, 否则将出现错误.

// 关闭索引:
POST address/_close // 启用English停用词token filter
PUT address/_settings
{
"analysis": {
"analyzer": {
"my_token_filter": { // 自定义的分词器名称
"type": "standard",
"stopwords": "_english_"
}
}
}
} // 打开索引:
POST address/_open

(2) 使用具有停词功能的分词器进行分词:

GET address/_analyze      // 指定索引
{
"analyzer": "my_token_filter", // 指定要使用的分词器
"text": "There-is & a DOG<br/> in house"
}

(3) 返回结果减少了停用词there, is, &, a, in等:

{
"tokens" : [
{
"token" : "dog",
"start_offset" : 13,
"end_offset" : 16,
"type" : "<ALPHANUM>",
"position" : 3
},
{
"token" : "br",
"start_offset" : 17,
"end_offset" : 19,
"type" : "<ALPHANUM>",
"position" : 4
},
{
"token" : "house",
"start_offset" : 25,
"end_offset" : 30,
"type" : "<ALPHANUM>",
"position" : 6
}
]
}

4 定制分词器

4.1 向索引中添加自定义的分词器

同样的, 在添加新的分词器之前, 必须先关闭索引, 添加完成后, 再打开索引进行搜索等操作.

PUT address/_settings
{
"analysis": {
"char_filter": {
"&_to_and": {
"type": "mapping",
"mappings": ["& => and"]
}
},
"filter": {
"my_stopwords": {
"type": "stop",
"stopwords": ["the", "a"]
}
},
"analyzer": {
"my_analyzer": { // 自定义的分析器名称
"type": "custom",
"char_filter": ["html_strip", "&_to_and"], // 跳过HTML标签, 将&符号转换为"and"
"tokenizer": "standard",
"filter": ["lowercase", "my_stopwords"] // 转换为小写
}
}
}
}

4.2 测试自定义分析器

GET address/_analyze
{
"analyzer": "my_analyzer", // 上面定义的分析器名称
"text": "There-is & a DOG<br/> in house"
}

可以发现, 返回的分析结果中已经对大写单词、HTML标签, 以及"&"做了处理.

{
"tokens" : [
// there和is
{
"token" : "and", // &被处理成了and
"start_offset" : 9,
"end_offset" : 10,
"type" : "<ALPHANUM>",
"position" : 2
},
// dog、in和house
]
}

4.3 向映射中添加自定义的分词器

PUT address/_mapping/province
{
"properties": {
"content": {
"type": "text",
"analyzer": "my_analyzer"
}
}
}

此时查看mapping信息:

GET address/_mapping

发现自定义的分析器已经配置到province上了:

{
"address": {
"mappings": {
"province": {
"properties": {
"area" : {
"type" : "float"
},
"content" : {
"type" : "text",
"analyzer" : "my_analyzer"
},
"name" : {
"type" : "text"
}
}
}
}
}
}

5 常见问题

在修改索引之前, 没有关闭索引, 修改时发生如下错误:

{
"error": {
"root_cause": [
{
"type": "illegal_argument_exception",
"reason": "Can't update non dynamic settings [[index.analysis.analyzer.my_token_filter.type, index.analysis.analyzer.my_token_filter.stopwords]] for open indices [[address/Ci6MJV4sTyuoF4r9aLvVZg]]"
}
],
"type": "illegal_argument_exception",
"reason": "Can't update non dynamic settings [[index.analysis.analyzer.my_token_filter.type, index.analysis.analyzer.my_token_filter.stopwords]] for open indices [[address/Ci6MJV4sTyuoF4r9aLvVZg]]"
},
"status": 400
}

查看本篇第[3]节的说明, 先关闭索引再执行修改操作.

版权声明

作者: 马瘦风(https://healchow.com)

出处: 博客园 马瘦风的博客(https://www.cnblogs.com/shoufeng)

感谢阅读, 如果文章有帮助或启发到你, 点个[好文要顶

ES 09 - 定制Elasticsearch的分词器 (自定义分词策略)的更多相关文章

  1. 【ELK】【docker】【elasticsearch】2.使用elasticSearch+kibana+logstash+ik分词器+pinyin分词器+繁简体转化分词器 6.5.4 启动 ELK+logstash概念描述

    官网地址:https://www.elastic.co/guide/en/elasticsearch/reference/current/docker.html#docker-cli-run-prod ...

  2. ElasticSearch中文分词器-IK分词器的使用

    IK分词器的使用 首先我们通过Postman发送GET请求查询分词效果 GET http://localhost:9200/_analyze { "text":"农业银行 ...

  3. 用lucene4.10.2分词器进行分词

    import java.util.Iterator; import java.util.LinkedList; import java.util.List; import org.apache.luc ...

  4. es的分词器analyzer

    analyzer   分词器使用的两个情形:  1,Index time analysis.  创建或者更新文档时,会对文档进行分词2,Search time analysis.  查询时,对查询语句 ...

  5. ES中文分词器安装以及自定义配置

    之前我们创建索引,查询数据,都是使用的默认的分词器,分词效果不太理想,会把text的字段分成一个一个汉字,然后搜索的时候也会把搜索的句子进行分词,所以这里就需要更加智能的分词器IK分词器了. ik分词 ...

  6. ElasticSearch(二十六)修改分词器及定制自己的分词器

    1.默认的分词器 standard 分词器 standard tokenizer:以单词边界进行切分standard token filter:什么都不做lowercase token filter: ...

  7. elasticsearch最全详细使用教程:入门、索引管理、映射详解、索引别名、分词器、文档管理、路由、搜索详解

    一.快速入门1. 查看集群的健康状况http://localhost:9200/_cat http://localhost:9200/_cat/health?v 说明:v是用来要求在结果中返回表头 状 ...

  8. ElasticSearch最全分词器比较及使用方法

    介绍:ElasticSearch 是一个基于 Lucene 的搜索服务器.它提供了一个分布式多用户能力的全文搜索引擎,基于 RESTful web 接口.Elasticsearch 是用 Java 开 ...

  9. Elasticsearch(10) --- 内置分词器、中文分词器

    Elasticsearch(10) --- 内置分词器.中文分词器 这篇博客主要讲:分词器概念.ES内置分词器.ES中文分词器. 一.分词器概念 1.Analysis 和 Analyzer Analy ...

随机推荐

  1. LOJ_6045_「雅礼集训 2017 Day8」价 _最小割

    LOJ_6045_「雅礼集训 2017 Day8」价 _最小割 描述: 有$n$种减肥药,$n$种药材,每种减肥药有一些对应的药材和一个收益. 假设选择吃下$K$种减肥药,那么需要这$K$种减肥药包含 ...

  2. oracle改造常见问题

    一. to_char: 将数值型或者日期型转化为字符型 (string) 日期到字符操作 select to_char(sysdate,'yyyy-MM-dd HH24:mi:ss') from du ...

  3. ionic3 懒加载在微信上缓存的问题

    1.懒加载是什么? 在ionic2中所有的组件.模块.服务.管道等都堆积在app.module.ts模块中,在页面初始化的时候会一次性加载所有的资源,导致资源过大,页面渲染缓慢,也导致app.modu ...

  4. jdbc 增删改查以及遇见的 数据库报错Can't get hostname for your address如何解决

    最近开始复习以前学过的JDBC今天肝了一晚上 来睡睡回笼觉,长话短说 我们现在开始. 我们先写一个获取数据库连接的jdbc封装类 以后可以用 如果不是maven环境的话在src文件下新建一个db.pr ...

  5. 轻松搞定JSONP跨域请求

    一.同源策略 要理解跨域,先要了解一下"同源策略".所谓同源是指,域名,协议,端口相同.所谓"同源策略",简单的说就是基于安全考虑,当前域不能访问其他域的东西. ...

  6. 搭建SpringCloud-Eureka 注册中心以及服务提供与调用

    纸上得来终觉浅,绝知此事要躬行啊~果然看着很easy,自己搞起来就是各种坑~各位看官,容我慢慢道来~ 关于springcloud是什么我就不废话了~ Eureka  Eureka(原来以为是缩写,原来 ...

  7. Spark学习之RDD编程总结

    Spark 对数据的核心抽象——弹性分布式数据集(Resilient Distributed Dataset,简称 RDD).RDD 其实就是分布式的元素集合.在 Spark 中,对数据的所有操作不外 ...

  8. 解决:git push error: failed to push some refs to

    出现错误的原因是github中的README.md文件不在本地代码目录中. 也就是说我们需要先将远程代码库中的任何文件先pull到本地代码库中,才能push新的代码到github代码库中. 使用如下命 ...

  9. 解决SpannableString在Android组件间传递时显示失效的问题

    问题:在A activity中传递一个SpannableString到B activity中,并最终传递到B activity中的TextView中,但是没有展示出Span效果. 解决:阅读TextV ...

  10. .Net Core中利用TPL(任务并行库)构建Pipeline处理Dataflow

    在学习的过程中,看一些一线的技术文档很吃力,而且考虑到国内那些技术牛人英语都不差的,要向他们看齐,所以每天下班都在疯狂地背单词,博客有些日子没有更新了,见谅见谅 什么是TPL? Task Parall ...