通过自己编写的字符转换插件,使Elasticsearch的日语搜索变得更加顺畅

首先

在Elasticsearch中有一個官方插件可以對日文進行形態解析。它非常方便地從長篇日文文章中提取出關鍵詞,但對於單詞數據或短日文可能不太擅長,有時候會出現問題。

例如,如果字符像”サイトウ”有几种写法,如”斉藤”、”斎藤”或”齋藤”,它们将无法完全匹配。
通过使用kuromoji_readingform词元过滤器,可以在很大程度上解决这个问题,但在使用它时,需要先使用kuromoji_tokenizer将每个词元分开。

请你考虑一下在搜索框中输入些什么,但是我认为这种搜索方式很少见。

image.png

我会这样做。

image.png

很多人希望自己能够决定搜索关键词的间隔,对吗?换句话说,

需要提前使用kuromoji_tokenizer将其分成每个令牌。

因为这个原因

Elasticsearch 自带日语搜索的自定义插件

希望查詢的狀況是這樣的

请提供一个原生中文的换句话:自制Elasticsearch日本语搜索插件。

如果数据被分割得像这样,而且搜索范围很大的话,只会出现大量垃圾数据在前面。

还有一点,在输入日语时,不是直接用汉字输入,而是先用假名输入然后再转换,对吧?
这样的话,在还没有转换成汉字之前,就无法得到预期的搜索结果,无法使用建议或增量搜索。

话虽说得有点长,但我们要解决的问题就在这里。

关于Elasticsearch的分析器

在Elasticsearch中,搜索词和搜索目标文档会通过分析器转化为便于搜索匹配的形式。详细内容可以在官方文档中找到,但简单概括来说,它由三个要素组成。

    1. 字符过滤器(char_filter)

 

    1. 分词器

 

    过滤器(token filter)

按照这个顺序进行处理。

每个 char_filter 用于对整个字符串进行转换,tokenizer 用于将其分割为标记,filter 则用于对每个标记进行转换。

我想要关注的是 character filter 的结果进入 tokenizer 这一点。
kuromoji_readingform token filter 只能在 token_filter 中使用 kuromoji_tokenizer,但如果可以在 character filter 中使用它,就可以自由地切分令牌。

汉字→假名转换插件

所以,我想着一定有其他人也在考虑同样的事情!然后我试着寻找,但没找到,所以我自己制作了一个汉字转假名的插件。

在插件开发中,我参考了 Elasticsearch 官方提供的 elasticsearch-analysis-kuromoji。

安裝

在Docker上准备Elasticsearch并安装插件。

$ docker run --name=es -p9200:9200 -d elasticsearch:5.6.5
9b8458e2c86d1990aca9ef64a8111d0d169aac8524a88737c020db855f00c3e8
$ docker exec es bin/elasticsearch-plugin install https://github.com/bgpat/elasticsearch-analysis-japanese/releases/download/v0.0.1/elasticsearch-analysis-japanese-es5.6.5.zip
-> Downloading https://github.com/bgpat/elasticsearch-analysis-japanese/releases/download/v0.0.1/elasticsearch-analysis-japanese-es5.6.5.zip
[=================================================] 100%   
-> Installed elasticsearch-analysis-japanese

我們還需要安裝 analysis-kuromoji 來進行比較分析。

$ docker exec es bin/elasticsearch-plugin install analysis-kuromoji
-> Downloading analysis-kuromoji from elastic
[=================================================] 100%   
-> Installed analysis-kuromoji

因为插件在下次启动时才会生效,所以需要重新启动。

$ docker restart es
es

验证 (Verifying)

因为有用于验证分析器功能的 API,因此我们使用它。(由于使用 curl 命令写 JSON 很麻烦,所以我们用 Insomnia 进行验证)

默认设置

如果不指定任何内容,将使用标准分析器。
通过使用标准分词器加小写词元过滤器的组合,可以很好地对英文进行规范化处理。
当然,这种分析器无法处理日语。

image.png

kuromoji 分析器 (Kuromoji

我尝试使用Kuromoji分析器。
它可以将日语文本正规化得十分好。

image.png

检索的文件还可以(?),但是如果搜索词是这样的话会有困难。

使用kuromoji_tokenizer + kuromoji_readingform token filter

这次我们将解构Kuromoji分析器,并使用Kuromoji_readingform令牌过滤器将其转换为假名。

image.png

当然,使用Kuromoji分析器时几乎没有什么变化。

使用空格为分词器,结合Kuromoji_readingform为令牌过滤器。

我想要使用whitespace标记器进行空格分割,并在kuromoji_readingform标记过滤器中进行假名转换。

image.png

尽管有空格分隔,但卡纳转换没有生效。

空格分词器 + 片假名转换

空白分词器和自定义插件katakana_transform。

image.png

我实现了我想要的功能。
顺便试试看。

image.png

现在,即使名字「齐藤」的汉字记不太清楚,也可以通过搜索找到相应的信息了。

实例使用

我们在 http://syllabus.kstm.cloud/ 使用了新开发的插件。(我们使用了所属大学的课程大纲作为搜索对象的文档)

除了自制插件外,还可以通过 icu_normalizer 进行假名到罗马字的转换,以便在罗马字输入过程中进行增量搜索。此外,为了提高搜索速度,还通过 edge-ngram tokenizer 对目标文档进行索引。(由于使用了正则表达式,prefix 查询可能较慢)
虽然也使用了 kuromoji analyzer 来创建索引,但当完全匹配时,它一定会排在前面。

代码已放置在 https://github.com/kstm-su/es-syllabus-web 上。

总结

我介绍了一种不限制分词器的假名转换插件,可以进行个性化的日语搜索机制。

因为假名转换算法只能使用 ipadic-neologd 中的单词,所以我还不能满足,但我认为它可以适应大多数情况。

广告
将在 10 秒后关闭
bannerAds