Elasticsearch 中文搜索:分析器与最佳实践
Elasticsearch 的内容索引中,分析和词元化至关重要,尤其处理非英语语言时。对于中文,由于汉字的特性以及词句之间缺乏空格,这一过程更为复杂。
本文探讨 Elasticsearch 中分析中文内容的几种方案,包括默认的中文分析器、paoding 插件、cjk 分析器、smartcn 分析器和 ICU 插件,并分析其优缺点及适用场景。
中文搜索的挑战
汉字是表意文字,代表一个词或语素(语言中最小的有意义单位)。组合在一起,其含义会发生变化,代表一个全新的词。另一个难点是词句之间没有空格,这使得计算机很难知道一个词从哪里开始,到哪里结束。
即使只考虑普通话(中国官方语言,也是世界上使用最广泛的汉语),也有数万个汉字,即使实际书面汉语只需要认识三千到四千个汉字。例如,“火山”(火山)实际上是以下两个汉字的组合:
我们的分词器必须足够聪明,避免将这两个汉字分开,因为它们组合在一起的意义与分开时不同。
另一个难点是使用的拼写变体:
Elasticsearch 中的中文分析器
目前,Elasticsearch 提供以下几种中文分析器:
Chinese
分析器,基于 Lucene 4 中已弃用的类;paoding
插件,虽然不再维护,但基于非常好的词典;cjk
分析器,它对内容进行二元组化;smartcn
分析器,一个官方支持的插件;这些分析器的差异很大,我们将通过一个简单的测试词“手机”来比较它们的性能。“手机”的意思是“手机”,它由两个汉字组成,分别表示“手”和“机”。“机”字还构成许多其他词:
我们的分词不能拆分这些汉字,因为如果我搜索“手机”,我不希望出现关于 Rambo 拥有机枪的任何文档。
我们将使用强大的 _analyze
API 测试这些方案:
<code class="language-bash">curl -XGET 'http://localhost:9200/chinese_test/_analyze?analyzer=paoding_analyzer1' -d '手机'</code>
默认的 Chinese
分析器: 它只将所有汉字分成词元。因此,我们得到两个词元:手和机。Elasticsearch 的 standard
分析器产生完全相同的输出。因此,Chinese
已弃用,很快将被 standard
取代,应避免使用。
paoding
插件: paoding
几乎是行业标准,被认为是一种优雅的解决方案。不幸的是,Elasticsearch 的插件没有维护,我只能在经过一些修改后才能在 1.0.1 版本上运行它。(安装步骤略,原文已提供)安装后,我们得到了一个新的 paoding
分词器和两个收集器:max_word_len
和 most_word
。默认情况下没有公开分析器,因此我们必须声明一个新的分析器。(配置步骤略,原文已提供)两种配置都提供了良好的结果,具有清晰且唯一的词元。在处理更复杂的句子时,其行为也非常好。
cjk
分析器: 非常简单的分析器,它只将任何文本转换成二元组。“手机”只索引 手机
,效果不错,但如果我们使用更长的词,例如“元宵节”(元宵节),则会生成两个词元:元宵和宵节,分别表示“元宵”和“宵节”。
smartcn
插件: 非常易于安装。(安装步骤略,原文已提供)它公开了一个新的 smartcn
分析器,以及 smartcn_tokenizer
分词器,使用 Lucene 的 SmartChineseAnalyzer
。它使用概率套件来查找单词的最佳分割,使用隐马尔可夫模型和大量的训练文本。因此,已经嵌入了一个相当好的训练词典——我们的示例被正确地分词了。
ICU 插件: 另一个官方插件。(安装步骤略,原文已提供)如果您处理任何非英语语言,建议使用此插件。它公开了一个 icu_tokenizer
分词器,以及许多强大的分析工具,如 icu_normalizer
、icu_folding
、icu_collation
等。它使用中文和日文字典,其中包含有关词频的信息,以推断汉字组。在“手机”上,一切正常,并且按预期工作,但在“元宵节”上,会产生两个词元:元宵和节——这是因为“元宵”和“节”比“元宵节”更常见。
结果比较 (表格略,原文已提供)
从我的角度来看,paoding
和 smartcn
获得了最佳结果。chinese
分词器非常糟糕,icu_tokenizer
在“元宵节”上有点令人失望,但在处理繁体中文方面表现非常好。
繁体中文支持
您可能需要处理来自文档或用户搜索请求的繁体中文。您需要一个规范化步骤将这些繁体输入转换为现代中文,因为像 smartcn
或 paoding
这样的插件无法正确处理它。
您可以通过您的应用程序进行处理,或者尝试使用 elasticsearch-analysis-stconvert
插件直接在 Elasticsearch 中进行处理。它可以双向转换繁体字和简体字。(安装步骤略,原文已提供)
最后一种解决方案是使用 cjk
:如果您无法正确分词输入,您仍然很有可能捕获所需的文档,然后使用 icu_tokenizer
(也相当好)来提高相关性。
进一步的改进
对于 Elasticsearch 的分析,没有完美的万能解决方案,中文也不例外。您必须根据获得的信息来组合和构建自己的分析器。例如,我在搜索字段上使用 cjk
和 smartcn
分词,使用多字段和多匹配查询。
(FAQ 部分略,原文已提供)
以上是有效的中文搜索与Elasticsearch的详细内容。更多信息请关注PHP中文网其他相关文章!