自定义ES分词器

本文详细介绍了Elasticsearch中的分词器构成,包括原始文本处理器、切词器和单词处理器的作用,以及如何自定义分词器。并通过实例展示了分词过程和不同查询场景(termvsmatch)的效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 分词器的组成和原理

ES的分词器主要由三部分组成:

(1)原始文本处理器-charactor filters

进行切词前,对原始文本进行预处理。如增加、删除和替换某些字符。该操作是为后续的切词作准备。

(2)切词器-tokenizer

按照规则对文本进行切词。如按照空格进行切词等。ES自带的切词器有 Standard Tokenizer(standard)、Whitespace Tokenizer(whitespace)等。

(3)单词处理器-token filters

将切词获取的单词进行加工。如大小写转化,删除stopwords,增加同义词等。

 

分词时,依次经过上述三项处理得到分词结果。

 

2 自定义分词器

下面是一个自定义分词器的案例,自定义分词器的以上三部分内容。

# custom_analyzer - 自定义分词器的名称
# char_filter - 原始文本预处理
# tokenizer - 按照指定的规则切词
# filter - 将切词后的结果进行加工

# _english_ 英文停用词,如 a,an,the

PUT /test_analyzer_index_001
{
  "settings": {
    "analysis": {
      "analyzer": {
        "custom_analyzer":{ 
          "type":"custom", 
          "char_filter":["emoticons"],
          "tokenizer": "threeVerticalLine",
          "filter":["english_stop"]
        }
      },
      "char_filter": {
        "emoticons":{ 
          "type" : "mapping",
          "mappings" : [
            ":) => _happy_",
            ":( => _sad_"
          ]
        }
      },
      "tokenizer": {
        "threeVerticalLine":{
          "type":"pattern",
          "pattern":"(\\|\\|\\|)"
        }
      },
      "filter": {
        "english_stop":{
          "type":"stop",
          "stopwords":"_english_"
        }
      }
    }
  },
  "mappings": {
    "dynamic": "strict",
    "properties": {
      "remark": {
        "type": "text",
        "analyzer": "custom_analyzer",
        "search_analyzer": "custom_analyzer"
      }
    }
  }
}

analyzer 用于指定对插入ES中的数据使用的分词器

search_analyzer 用于指定查询入参使用的分词器

 

3 测试分词效果

3.1 测试分词

POST test_analyzer_index_001/_analyze
{
  "analyzer": "custom_analyzer",
  "text": "进口药品|注册证H20130650|||进口药品注册证h20130650|||h20130650_haha_a_the|||tom :)|||jack :(|||a|||an|||the"
}

或者
POST test_analyzer_index_001/_analyze
{
  "field":"remark",
  "text": "进口药品|注册证H20130650|||进口药品注册证h20130650|||h20130650_haha_a_the|||tom :)|||jack :(|||a|||an|||the"
}

分词结果如下所示。

{
  "tokens" : [
    {
      "token" : "进口药品|注册证H20130650",
      "start_offset" : 0,
      "end_offset" : 17,
      "type" : "word",
      "position" : 0
    },
    {
      "token" : "进口药品注册证h20130650",
      "start_offset" : 20,
      "end_offset" : 36,
      "type" : "word",
      "position" : 1
    },
    {
      "token" : "h20130650_haha_a_the",
      "start_offset" : 39,
      "end_offset" : 59,
      "type" : "word",
      "position" : 2
    },
    {
      "token" : "tom _happy_",
      "start_offset" : 62,
      "end_offset" : 68,
      "type" : "word",
      "position" : 3
    },
    {
      "token" : "jack _sad_",
      "start_offset" : 71,
      "end_offset" : 78,
      "type" : "word",
      "position" : 4
    }
  ]
}

由结果可知,分词时,先按照emoticons规则进行了原始文本处理,然后根据threeVerticalLine规则进行分词(即使用"|||"分词),最后根据english_stop规则对英文停用词进行去除。

3.2 测试查询

下面来测试下查询效果。

3.2.1 插入数据

PUT /test_analyzer_index_001/_doc/1
{
  "remark": "进口药品|注册证H20130650|||进口药品注册证h20130650|||h20130650_haha_a_the|||tom :)|||jack :(|||a|||an|||the"
}

3.2.2 查询所有数据

GET /test_analyzer_index_001/_search
{
  "query": {
    "match_all": {}
  }
}

结果如下

{
  
    "hits" : [
      {
        "_index" : "test_analyzer_index_001",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "remark" : "进口药品|注册证H20130650|||进口药品注册证h20130650|||h20130650_haha_a_the|||tom :)|||jack :(|||a|||an|||the"
        }
      }
    ]
  }
}

3.2.3 term查询

term 查询对输入不做分词,会将输入作为一个整体,到倒排索引中查找准确的词项。

(1)场景1-可召回插入的数据

GET /test_analyzer_index_001/_search
{
  "query": {
    "term": {
      "remark": "进口药品注册证h20130650"
    }
  }
}

(2)场景2-查询结果为空

以下查询结果为空,因为”进口药品|注册证H20130650|||进口药品注册证h20130650|||h20130650_haha_a_the|||tom :)|||jack :(|||a|||an|||the“在新增ES倒排索引时会进行分词,将”tom :)“转化为了”tom _happy_“,因此在倒排索引中存储的值为分词后的值:”tom _happy_“,因此使用”tom :)“查询不到数据。

GET /test_analyzer_index_001/_search
{
  "query": {
    "term": {
      "remark": "tom :)"
    }
  }
}

3.2.4 match查询

match 查询对输入的查询条件进行分词,生成一个供查询的词项列表,然后每个词项逐个进行底层的查询,最终将结果进行合并。

(1)场景1-可召回插入的数据

分词后的入参为 ”进口药品|注册证H20130650“、”tom _happy_“ 和 ”jack _sad_“。

GET /test_analyzer_index_001/_search
{
  "query": {
    "match": {
      "remark": "进口药品|注册证H20130650|||tom :)|||jack :("
    }
  }
}

(2)场景2-可召回插入的数据

分词后的入参为”tom _happy_“ 。

GET /test_analyzer_index_001/_search
{
  "query": {
    "match": {
      "remark": "tom :)"
    }
  }
}

4 参考文献

(1)Tokenizer reference | Elasticsearch Guide [7.10] | Elastic

 

### 如何在 Elasticsearch 中使用 IK 分词器进行自定义分词 #### 插件安装 为了在 Elasticsearch 中使用 IK 分词器,首先需要安装插件。可以通过以下命令完成插件的安装: ```bash bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.3.0/elasticsearch-analysis-ik-7.3.0.zip ``` 此命令会下载并安装适用于 Elasticsearch 7.3.0 的 IK 分词器插件[^4]。 #### 配置文件说明 IK 分词器的核心配置文件位于 `config/analysis-ik` 文件夹下。主要涉及两个重要文件: 1. **custom.dic**:用于添加自定义词条。 2. **stopwords.txt**:用于指定停用词列表。 这些文件的具体路径可能因 Elasticsearch 安装目录而异,通常可以在 `/path/to/elasticsearch/config/analysis-ik/` 下找到[^3]。 #### 自定义分词设置 通过修改上述配置文件实现自定义分词功能。以下是具体方法: ##### 添加自定义词条 编辑 `custom.dic` 文件,在其中添加希望被识别为独立词语的内容。例如: ``` 人工智能 机器学习 自然语言处理 ``` 保存后重启 Elasticsearch 生效。 ##### 设置停用词 如果某些单词不需要参与索引或查询过程,则可将其加入到 `stopwords.txt` 文件中。例如: ``` 的 了 是 ``` 同样需保存更改并重启服务以使改动生效。 #### 测试自定义分词效果 创建一个测试索引来验证自定义分词的效果。执行如下 REST API 请求: ```json PUT test_index { "settings": { "analysis": { "analyzer": { "my_ik_analyzer": { "type": "custom", "tokenizer": "ik_max_word" } } } }, "mappings": { "properties": { "content": { "type": "text", "analyzer": "my_ik_analyzer" } } } } ``` 随后向该索引插入文档数据,并利用 `_analyze` 接口查看实际分词结果: ```json POST _analyze { "analyzer": "my_ik_analyzer", "text": "这是一段关于人工智能和机器学习的文章" } ``` 返回的结果应展示按照所设规则拆解后的词汇列表[^2]。 #### 注意事项 确保使用的 IK 分词器版本与当前运行中的 Elasticsearch 版本相匹配;否则可能导致兼容性问题或者无法正常启动集群服务。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值