首页 > 后端开发 > php教程 > 有效的中文搜索与Elasticsearch

有效的中文搜索与Elasticsearch

William Shakespeare
发布: 2025-02-19 08:28:11
原创
443 人浏览过

Elasticsearch 中文搜索:分析器与最佳实践

Elasticsearch 的内容索引中,分析和词元化至关重要,尤其处理非英语语言时。对于中文,由于汉字的特性以及词句之间缺乏空格,这一过程更为复杂。

本文探讨 Elasticsearch 中分析中文内容的几种方案,包括默认的中文分析器、paoding 插件、cjk 分析器、smartcn 分析器和 ICU 插件,并分析其优缺点及适用场景。

中文搜索的挑战

汉字是表意文字,代表一个词或语素(语言中最小的有意义单位)。组合在一起,其含义会发生变化,代表一个全新的词。另一个难点是词句之间没有空格,这使得计算机很难知道一个词从哪里开始,到哪里结束。

即使只考虑普通话(中国官方语言,也是世界上使用最广泛的汉语),也有数万个汉字,即使实际书面汉语只需要认识三千到四千个汉字。例如,“火山”(火山)实际上是以下两个汉字的组合:

  • 火:火
  • 山:山

我们的分词器必须足够聪明,避免将这两个汉字分开,因为它们组合在一起的意义与分开时不同。

另一个难点是使用的拼写变体:

  • 简体中文:书法
  • 繁体中文,更复杂、更丰富:書法
  • 拼音,普通话的罗马化形式:shū fǎ

Elasticsearch 中的中文分析器

目前,Elasticsearch 提供以下几种中文分析器:

  • 默认的 Chinese 分析器,基于 Lucene 4 中已弃用的类;
  • paoding 插件,虽然不再维护,但基于非常好的词典;
  • cjk 分析器,它对内容进行二元组化;
  • smartcn 分析器,一个官方支持的插件;
  • ICU 插件及其分词器。

这些分析器的差异很大,我们将通过一个简单的测试词“手机”来比较它们的性能。“手机”的意思是“手机”,它由两个汉字组成,分别表示“手”和“机”。“机”字还构成许多其他词:

  • 机票:机票
  • 机器人:机器人
  • 机枪:机枪
  • 机遇:机遇

我们的分词不能拆分这些汉字,因为如果我搜索“手机”,我不希望出现关于 Rambo 拥有机枪的任何文档。

我们将使用强大的 _analyze API 测试这些方案:

curl -XGET 'http://localhost:9200/chinese_test/_analyze?analyzer=paoding_analyzer1' -d '手机'
登录后复制

Efficient Chinese Search with Elasticsearch

  • 默认的 Chinese 分析器: 它只将所有汉字分成词元。因此,我们得到两个词元:手和机。Elasticsearch 的 standard 分析器产生完全相同的输出。因此,Chinese 已弃用,很快将被 standard 取代,应避免使用。

  • paoding 插件: paoding 几乎是行业标准,被认为是一种优雅的解决方案。不幸的是,Elasticsearch 的插件没有维护,我只能在经过一些修改后才能在 1.0.1 版本上运行它。(安装步骤略,原文已提供)安装后,我们得到了一个新的 paoding 分词器和两个收集器:max_word_lenmost_word。默认情况下没有公开分析器,因此我们必须声明一个新的分析器。(配置步骤略,原文已提供)两种配置都提供了良好的结果,具有清晰且唯一的词元。在处理更复杂的句子时,其行为也非常好。

  • cjk 分析器: 非常简单的分析器,它只将任何文本转换成二元组。“手机”只索引 手机,效果不错,但如果我们使用更长的词,例如“元宵节”(元宵节),则会生成两个词元:元宵和宵节,分别表示“元宵”和“宵节”。

  • smartcn 插件: 非常易于安装。(安装步骤略,原文已提供)它公开了一个新的 smartcn 分析器,以及 smartcn_tokenizer 分词器,使用 Lucene 的 SmartChineseAnalyzer。它使用概率套件来查找单词的最佳分割,使用隐马尔可夫模型和大量的训练文本。因此,已经嵌入了一个相当好的训练词典——我们的示例被正确地分词了。

  • ICU 插件: 另一个官方插件。(安装步骤略,原文已提供)如果您处理任何非英语语言,建议使用此插件。它公开了一个 icu_tokenizer 分词器,以及许多强大的分析工具,如 icu_normalizericu_foldingicu_collation 等。它使用中文和日文字典,其中包含有关词频的信息,以推断汉字组。在“手机”上,一切正常,并且按预期工作,但在“元宵节”上,会产生两个词元:元宵和节——这是因为“元宵”和“节”比“元宵节”更常见。

结果比较 (表格略,原文已提供)

从我的角度来看,paodingsmartcn 获得了最佳结果。chinese 分词器非常糟糕,icu_tokenizer 在“元宵节”上有点令人失望,但在处理繁体中文方面表现非常好。

繁体中文支持

您可能需要处理来自文档或用户搜索请求的繁体中文。您需要一个规范化步骤将这些繁体输入转换为现代中文,因为像 smartcnpaoding 这样的插件无法正确处理它。

您可以通过您的应用程序进行处理,或者尝试使用 elasticsearch-analysis-stconvert 插件直接在 Elasticsearch 中进行处理。它可以双向转换繁体字和简体字。(安装步骤略,原文已提供)

最后一种解决方案是使用 cjk:如果您无法正确分词输入,您仍然很有可能捕获所需的文档,然后使用 icu_tokenizer(也相当好)来提高相关性。

进一步的改进

对于 Elasticsearch 的分析,没有完美的万能解决方案,中文也不例外。您必须根据获得的信息来组合和构建自己的分析器。例如,我在搜索字段上使用 cjksmartcn 分词,使用多字段和多匹配查询。

(FAQ 部分略,原文已提供)

以上是有效的中文搜索与Elasticsearch的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板