最近想为搜索引擎加上拼音搜索,在查阅网上信息之后找到两个插件,一个叫elasticsearch-analysis-pinyin (下文简称pinyin),另一个叫elasticsearch-analysis-lc-pinyin (下文简称lc-pinyin)。名字很相似,也就是后面多个lc。
pinyin是跟最火的中文分词插件ik同属一个项目组的。这款拼音分词插件同样是占据了市场的大多数。而lc-pinyin看起来对中文和拼音的混输支持的挺好,所以决定把两个都装上去试试了。
首先声明一下,我的elasticsearch版本是1.5.4。
pinyin分词测试
我首选的是pinyin,毕竟我已经用了ik,感觉他俩应该会比较般配。
pinyin的项目打开以后看到readme上面的文档说明也是挺详尽的,而对应我的es版本,似乎只能用最低的1.2版,几番对照之后安装了可以接受的最高版1.2.2,不得不说,这个版本下面的文档就差远了(也许功能也少点)。不过他提供的内容是挺多,一个analyzer,两个tokenizer和一个token-filter,这样就可以用它来搞各种自定义的拼音分词,比如配合nGram过滤器,还可以结合同义词过滤器等。比如结合nGram的效果:
PUT /test
{
"index" : {
"analysis" : {
"analyzer" : {
"pinyin_analyzer" : {
"tokenizer" : "my_pinyin",
"filter" : ["standard","nGram"]
}
},
"tokenizer" : {
"my_pinyin" : {
"type" : "pinyin",
"first_letter" : "prefix",
"padding_char" : ""
}
}
}
}
}
我们看一下他的分词效果:
执行http://localhost:9200/test/_analyze?text=刘德华&analyzer=pinyin_analyzer
{
"tokens": [
{
"token": "l",
"start_offset": 0,
"end_offset": 3,
"type": "word",
"position": 1
},
{
"token": "ld",
"start_offset": 0,
"end_offset": 3,
"type": "word",
"position": 1
},
{
"token": "d",
"start_offset": 0,
"end_offset": 3,
"type": "word",
"position": 1
},
{
"token": "dh",
"start_offset": 0,
"end_offset": 3,
"type": "word",
"position": 1
},
……
{
"token": "hu",
"start_offset": 0,
"end_offset": 3,
"type": "word",
"position": 1
},
{
"token": "u",
"start_offset": 0,
"end_offset": 3,
"type": "word",
"position": 1
},
{
"token": "ua",
"start_offset": 0,
"end_offset": 3,
"type": "word",
"position": 1
},
{
"token": "a",
"start_offset": 0,
"end_offset": 3,
"type": "word",
"position": 1
}
]
}
中间略去100+行,区区三个字,便搞出洋洋洒洒几十个分词,看起来也是有点蒙逼,而且“ua”这样的词也是有点鸡肋,谁会用“ua”搜“华”字呢,其实主要是nGram干的,我们还是上面的分词,去掉nGram过滤器就是下面的样子了:
{
"tokens": [
{
"token": "ldhliudehua",
"start_offset": 0,
"end_offset": 3,
"type": "word",
"position": 1
}
]
}
刘德华的拼音缩写加全拼,如此而已,而他的配置参数first_letter也只是决定前面ldh这个缩写出现的位置而已(例子中是prefix,即前缀)。
加了nGram的效果是太宽泛,而去掉则完全没有分词效果,那就先按下不表,我试试另一个吧。
lc-pinyin分词测试
其实内心对lc-pinyin有点喜欢,因为看了下面这一篇帖子中的演示效果是很合我心意的。
http://blog.csdn.net/chennanymy/article/details/52336368
而安装lc-pinyin也相对简单,因为只有两个选择,我安装了1.4.5版。
而装好之后也没什么花样,通过简单配置之后就有了lc_index和lc_search,一个用于创建索引,一个用于搜索。我们同样用上面的方式来测试分词效果:
执行http://localhost:9200/test/_analyze?text=刘德华&analyzer=lc_index
{
"tokens": [
{
"token": "刘",
"start_offset": 0,
"end_offset": 1,
"type": "word",
"position": 1
},
{
"token": "liu",
"start_offset": 0,
"end_offset": 1,
"type": "word",
"position": 1
},
{
"token": "l",
"start_offset": 0,
"end_offset": 1,
"type": "word",
"position": 1
},
{
"token": "德",
"start_offset": 1,
"end_offset": 2,
"type": "word",
"position": 2
},
{
"token": "de",
"start_offset": 1,
"end_offset": 2,
"type": "word",
"position": 2
},
……
这里我只粘贴了一半内容,我们可以看出,他做了简单的按中文字分词,然后保存了每个字的全拼和首字母。看起来就很干净简洁,而且这样支持中文混搜。混合搜索对我很有用,因为这个索引我是用于搜索引擎的输入框提示的,这种情况出现在用户已经输入了前面的一两个中文字,然后正在输入法中选后面的字的时候。比如我打“客厅”,我刚打完“客”,正在输打“厅”,这时输入框中就是“客ting”,这时无需用户继续在输入法中选择“厅”字,我已经可以给出“客厅”了。
小结
所以使用lc-pinyin,基本上可以零配置实现我要的效果了,这也是它的优势所在,不过你若想多一点自定义的东西,恐怕是很难实现的。
而pinyin的缺点也正是他有许多可自定义的东西,而且他的最新版有更多配置项,对于新手来说可能门槛略高,但是对于高手来说可以实现更多想要的东西。但不得不吐槽的是1.2.2版本的两个(也许还有更多,不过我没有在文档找到)配置项也是有点鸡肋,也或许是我不懂用吧,总之如果你的ES也是1.*版本就不推荐用pinyin了,除非你愿意花更多时间去探索他的隐藏关卡。
