当前位置: 首页 > 中文分词, 搜索 > 正文

ik分词”词元长度优先”导致在lucene中高亮显示错位

1 星2 星3 星4 星5 星 (2 次投票, 评分: 5.00, 总分: 5)
Loading ... Loading ...
baidu_share

现象:在索引时如果一个Document对象只包含一个名为”content”的Field,即

1
doc.add(new Field("content", "大家好", Store.YES, Index.ANALYZED, TermVector.WITH_POSITIONS_OFFSETS))

这样在高亮时是没问题的。
但是如果一个Document对象包含两个或两个以上名为”content”的Field,即

1
2
3
4
5
6
doc.add(new Field("content", "大家好", Store.YES, Index.ANALYZED, TermVector.WITH_POSITIONS_OFFSETS));
doc.add(new Field("content", "这里是随便的一句话", Store.YES, Index.ANALYZED, TermVector.WITH_POSITIONS_OFFSETS));
 
在搜索"随便"时的高亮结果为"大家好;这里<b>是随<b/>便的一句话",而希望的结果是"大家好;这里是<b>随便<b/>的一句话"1:如果一个Document对象包含多个同名Field,在高亮时需要把所有的Field值加起来,用一个字符隔开,前面示例的分隔符为半角分号
注2:本问题只有在使用IK分词时产生,使用其他比如StrandardAnalyzer不存在。

原因:IK在对“大家好”分词时的结果为

1
2
[0-3] 大家好
[0-2] 大家

导致在索引时计算offset和position错位一个字符,如果IK分词结果为

1
2
[0-2] 大家
[0-3] 大家好

则不会出现问题

解决办法:修改Lexeme.compareTo方法中如下代码

1
2
3
4
5
6
7
8
9
10
if(this.begin == other.getBegin()){                  
  //词元长度优先                   
  if(this.length > other.getLength()){                           
    return -1;                   
  }else if(this.length == other.getLength()){                           
    return 0;                   
  }else {
     return 1;                   
  }                              
}

将其中的“词元长度优先”改为相反,即返回值-1和1互换位置。

本文固定链接: http://www.chepoo.com/ik-word-element-length-priority-lucene-highlight-error.html | IT技术精华网

ik分词”词元长度优先”导致在lucene中高亮显示错位:等您坐沙发呢!

发表评论