分词问题导致查询不到举例解释说明

问题

经常有同事反馈查询不到,也有很多同事觉得能查到,但是对为什么能查到感到有点疑惑

分词器

当前使用的是IK分词器,该分词器有两个分词模式,一个是ik_max_word分词。该分词器会尽量的多分出来词语,而另一个ik_smart则会分的少很多,只有主要的词,后续举例。显然,第一个结果太碎,而第二个会在查找时错漏很多。为保证尽量全,我们当前使用的分词器是第一个,效果会好一点,但是错分也是存在的。

原因

那么我们下面就举例说明。
先说分词结果,以“中华人民共和国人民大会堂”为例:

分词器分词

  • Ik_max_word会分成“中华人民共和国、中华人民、中华、华人、人民共和国、人民、共和国、共和、国人、人民大会堂、人民大会、人民、大会堂、大会、会堂”
  • ik_smart则会分“中华人民共和国、人民大会堂”

看看,是不是差了非常多?为了能尽可能的满足查询,我们当前的Ik_max_word!可是用这个就保险了么?

去掉一个堂

可以继续往下看,我再分一个 “中华人民共和国人民大会”,比上一个少了1个字,结果会变化很大么?
这个结果是:“中华人民共和国、中华人民、中华、华人、人民共和国、人民、共和国、共和、国人、人民大会、人民、大会”。看上去变化不大,只是把带堂的结果去掉了是吧,可是查询时候不是这样的。

新建了一个index,专门说明这个情况,我向新的index写了一句话“我在中华人民共和国人民大会堂宣誓入党”,查询结果(因为我们仅使用了match_phrase和match_phrase_prefix,仅查看这两个的区别):

  • 搜索中华人民共和国人民大会堂能查到
  • 搜索中华人民共和国人民大会就不能查到
  • 搜索中华人民共和国人民大会就不能查到,slop=1也查不到
  • 搜索中华人民共和国人民大会就不能查到,slop=2却可以

这里就要考虑是为什么了?

大家可以看到,在索引排序时,人民大会、人民、大会这三个词的顺序编码两个是不一致的,但是最大是差别2,因此slop=2时是可以搜到的。

可是这样就行了么?

再举一个例子;,以“六一儿童节”和“六一儿童节节日快乐”为例,当文章中存在六一儿童节节日快乐而搜索六一儿童节时,就搜不出,因为不匹配!而搜索六一可能就能匹配上。分词结果如下:

我们看看查询结果:

  • 搜索六一可以搜到,证明文章确实存在:
  • 搜索六一儿童搜不到
  • 搜索六一儿童 slop=1 就可以搜到
  • 搜索六一儿童节就搜不到,即使我slop都开到999了
  • 搜索六一儿童节节可以搜到

如上,有谁会去搜索六一儿童节节呢?只会感觉检索不准罢了

附,最后一个解决办法,使用match_phrase_prefix,当用它搜索六一儿童节时,其实它搜索的类似是 六一儿童节*的数据,即最后一个分词只要是以节开头的,都算作匹配。因此节可以匹配上节节,所以就可以查询到了。但是这个只是在词的末尾有效,碰到在词中是不生效的,因此还会有些是搜不出来的,并且相比match_phrase是更消耗资源的,只能算是没有办法的办法。同时,这个是后缀可以,但是前序就不行,例如第一个例子搜索和国就搜不出来一样