原文出处:http://code.google.com/p/ik-analyzer/issues/detail?id=23&can=1

现象:在索引时如果一个Document对象只包含一个名为"content"的Field,即
********
doc.add(new Field("content", "大家好", Store.YES, Index.ANALYZED, TermVector.WITH_POSITIONS_OFFSETS))
********
这样在高亮时是没问题的。
但是如果一个Document对象包含两个或两个以上名为"content"的Field,即
********
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在对“大家好”分词时的结果为
********
[0-3] 大家好
[0-2] 大家
********
导致在索引时计算offset和position错位一个字符,如果IK分词结果为
********
[0-2] 大家
[0-3] 大家好
********
则不会出现问题

解决办法:修改Lexeme.compareTo方法中如下代码
********
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互换位置。