主页 >> 程序猿的东西 >> elasticsearch拼音插件探索

elasticsearch拼音插件探索

最近想为搜索引擎加上拼音搜索,在查阅网上信息之后找到两个插件,一个叫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了,除非你愿意花更多时间去探索他的隐藏关卡。

发表评论