当前位置:首页 > 技术 > 正文内容

ElasticSearch中高效中文分词实践指南

访客 技术 2026年7月10日 1

一、分词基础概念

当文档被存储到ElasticSearch中时,系统会使用分词器从文本内容中提取出多个词元(token),这些词元用于支持索引的构建和后续的搜索操作。ElasticSearch内置了多种分词器,但这些内置分词器对中文文本的处理效果并不理想。下面通过实际案例来展示内置分词器的处理差异。

首先,我们向ElasticSearch发送一个REST请求,测试英文文本的分词效果:

POST http://localhost:9200/_analyze
{  
    "text": "hello world"  
}

请求成功后,系统返回如下结果:

{
  "tokens": [
    {
      "token": "hello",
      "start_offset": 0,
      "end_offset": 5,
      "type": "<ALPHANUM>",
      "position": 0
    },
    {
      "token": "world",
      "start_offset": 6,
      "end_offset": 11,
      "type": "<ALPHANUM>",
      "position": 1
    }
  ]
}

从上述结果可以看出,"hello world"被正确地分割为两个独立的单词,这是因为英文文本天然以空格作为分隔符,因此这种分词方式非常合理。

接下来,我们测试一段中文文本的分词效果:

POST http://localhost:9200/_analyze
{  
    "text": "科学技术是第一生产力"  
}

系统返回的分词结果如下:

{
  "tokens": [
    {
      "token": "科",
      "start_offset": 0,
      "end_offset": 1,
      "type": "<IDEOGRAPHIC>",
      "position": 0
    },
    {
      "token": "技",
      "start_offset": 1,
      "end_offset": 2,
      "type": "<IDEOGRAPHIC>",
      "position": 1
    },
    {
      "token": "术",
      "start_offset": 2,
      "end_offset": 3,
      "type": "<IDEOGRAPHIC>",
      "position": 2
    },
    {
      "token": "是",
      "start_offset": 3,
      "end_offset": 4,
      "type": "<IDEOGRAPHIC>",
      "position": 3
    },
    {
      "token": "第",
      "start_offset": 4,
      "end_offset": 5,
      "type": "<IDEOGRAPHIC>",
      "position": 4
    },
    {
      "token": "一",
      "start_offset": 5,
      "end_offset": 6,
      "type": "<IDEOGRAPHIC>",
      "position": 5
    },
    {
      "token": "生",
      "start_offset": 6,
      "end_offset": 7,
      "type": "<IDEOGRAPHIC>",
      "position": 6
    },
    {
      "token": "产",
      "start_offset": 7,
      "end_offset": 8,
      "type": "<IDEOGRAPHIC>",
      "position": 7
    },
    {
      "token": "力",
      "start_offset": 8,
      "end_offset": 9,
      "type": "<IDEOGRAPHIC>",
      "position": 8
    }
  ]
}

从结果可以看出,内置分词器将每个汉字都独立分开,这种处理方式对于中文分词来说显然是不合理的,因为它无法识别词语和短语。默认情况下,ElasticSearch使用名为"standard"的分词器处理文本,这可以通过显式指定analyzer参数来确认:

POST http://localhost:9200/_analyze
{  
    "analyzer": "standard",
    "text": "科学技术是第一生产力"  
}

幸运的是,社区提供了多种优秀的第三方中文分词器,能够与ElasticSearch良好集成。在本文中,我们将重点介绍IK分析器的配置和使用方法。

二、IK分析器安装

ElasticSearch提供了插件管理脚本elasticsearch-plugin(在Windows系统下为elasticsearch-plugin.bat),该脚本位于ElasticSearch安装目录的bin目录下。该脚本支持三种主要操作,通过参数进行区分:

  1. elasticsearch-plugin install 插件地址 - 安装指定插件到当前ElasticSearch节点
  2. elasticsearch-plugin list - 显示当前节点已安装的插件列表
  3. elasticsearch-plugin remove 插件名称 - 删除已安装的插件

安装IK分析器时,插件地址可以是远程URL(在线安装)或本地文件路径(离线安装)。对于IK分析器,无论是远程还是本地安装,都需要提供zip格式的安装包。需要注意的是,IK分析器的版本必须与ElasticSearch版本保持一致。本文以ElasticSearch 7.8.0为例,因此使用相同版本的IK分析器。

通过远程URL安装IK分析器的命令如下:

./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.8.0/elasticsearch-analysis-ik-7.8.0.zip

如果无法从远程下载,也可以使用本地文件进行安装。在Linux系统下,本地安装命令为:

./bin/elasticsearch-plugin install file:///home/user/elasticsearch-analysis-ik-7.8.0.zip

在Windows系统下,本地安装命令为:

elasticsearch-plugin.bat install file:///D:/user/elasticsearch-analysis-ik-7.8.0.zip

安装完成后,ElasticSearch的plugins目录下会出现一个analysis-ik目录(包含解压后的IK分析器文件),同时config目录下也会生成一个analysis-ik目录(用于存放自定义词典)。为了使插件生效,需要重启ElasticSearch服务。

新版本的IK分析器提供了两种分词器:ik_max_word和ik_smart,它们在分粒度和效果上有所不同。

三、IK分析器使用方法

首先,我们测试ik_max_word分词器的效果:

POST http://localhost:9200/_analyze
{  
    "analyzer": "ik_max_word",
    "text": "科学技术是第一生产力"  
}

系统返回的分词结果如下:

{
  "tokens": [
    {
      "token": "科技",
      "start_offset": 0,
      "end_offset": 2,
      "type": "CN_WORD",
      "position": 0
    },
    {
      "token": "技术",
      "start_offset": 1,
      "end_offset": 3,
      "type": "CN_WORD",
      "position": 1
    },
    {
      "token": "科学技术",
      "start_offset": 0,
      "end_offset": 4,
      "type": "CN_WORD",
      "position": 2
    },
    {
      "token": "是",
      "start_offset": 4,
      "end_offset": 5,
      "type": "CN_WORD",
      "position": 3
    },
    {
      "token": "第一",
      "start_offset": 5,
      "end_offset": 7,
      "type": "CN_WORD",
      "position": 4
    },
    {
      "token": "生产力",
      "start_offset": 7,
      "end_offset": 10,
      "type": "CN_WORD",
      "position": 5
    },
    {
      "token": "生产",
      "start_offset": 7,
      "end_offset": 9,
      "type": "CN_WORD",
      "position": 6
    }
  ]
}

接下来,我们测试ik_smart分词器的效果:

POST http://localhost:9200/_analyze
{  
    "analyzer": "ik_smart",
    "text": "科学技术是第一生产力"  
}

系统返回的分词结果如下:

{
  "tokens": [
    {
      "token": "科技",
      "start_offset": 0,
      "end_offset": 2,
      "type": "CN_WORD",
      "position": 0
    },
    {
      "token": "技术",
      "start_offset": 2,
      "end_offset": 4,
      "type": "CN_WORD",
      "position": 1
    },
    {
      "token": "是",
      "start_offset": 4,
      "end_offset": 5,
      "type": "CN_WORD",
      "position": 2
    },
    {
      "token": "第一",
      "start_offset": 5,
      "end_offset": 7,
      "type": "CN_WORD",
      "position": 3
    },
    {
      "token": "生产力",
      "start_offset": 7,
      "end_offset": 10,
      "type": "CN_WORD",
      "position": 4
    }
  ]
}

对比两种分词器的结果,可以明显看出ik_max_word比ik_smart提取的词汇更多粒度更细,但这也意味着使用ik_max_word会占用更多的存储空间。在实际应用中,应根据具体需求选择合适的分词器。

四、IK分析器自定义词典

在某些场景下,IK分析器内置的词典可能无法满足特定需求(如专业术语、品牌名称等)。IK分析器支持自定义词典功能,允许用户添加特定词汇,使系统能够正确识别这些词条。

以"人工智能技术发展迅速"为例,假设我们希望系统能够识别"智能技术"这一专业术语,可以按照以下步骤自定义词典:

  1. 创建一个扩展名为.dic的文本文件,每行包含一个自定义词条,例如创建custom_terms.dic文件:
智能技术
大数据
云计算
  1. 将上述文件保存到ElasticSearch安装目录下的config/analysis-ik目录中(可以创建子目录组织不同类别的词典)
  2. 修改IK分析器的配置文件IKAnalyzer.cfg.xml(位于config/analysis-ik目录),添加自定义词典配置:
<entry key="ext_dict">custom_terms.dic</entry>
  1. 重启ElasticSearch服务使配置生效

配置完成后,再次使用ik_max_word分词器测试"人工智能技术发展迅速":

POST http://localhost:9200/_analyze
{  
    "analyzer": "ik_max_word",
    "text": "人工智能技术发展迅速"  
}

系统返回的分词结果将包含自定义的"智能技术"词条。需要注意的是,ik_smart分词器可能无法识别所有自定义词条,这是因为其分词策略更为保守。

五、设置默认分词器

可以在创建索引时指定默认使用的分词器,避免每次查询时都需要显式指定。以下是设置ik_smart为默认分词器的示例:

PUT http://localhost:9200/my_index
{
    "settings" : {
        "index" : {
            "analysis.analyzer.default.type": "ik_smart",
            "analysis.search_analyzer.default.type":"ik_smart"
        }
    }
}

可以通过以下查询验证设置是否生效:

GET http://localhost:9200/my_index/_settings

响应结果将显示当前索引的配置信息,包括默认分词器的设置。

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。