今天抽空研究了一下Solr的一元分词,就是根据使用的效果来得到一个感性的人是。在自带的analysis页面中可以很好的看出分词的效果,以及匹配的情况。这里我做了几组实验,基本得到了我想要的答案。

实验一:一元分词与不分词混合查询匹配情况

    我先是让文本的分词为一元分词,然后查询的内容采用不分词。试了一下,发现我这里用多个字的词就匹配不到结果,只有单字可以。这说明分词的结果是作为一个原子,要完全匹配才可以。换过来,如果原文不分词,查询结果必须要完全对应上才能查到结果。

实验二:一元分词的索引和查询匹配情况

    这次让文本的分词用一元,查询的内容也用一元分词。这下只要你是在原文中拷贝一段内容,不论是否是有意义的截断,都是可以得到匹配。简单看了一下verbose的输出,这里其实还是按字去查询匹配的,但是结果必须是严格按照查询字的顺序才算是命中,应该是根据每个字之间的offset来判断的。
    这样最大的优点就是你在分词阶段不用词库,但是有新词出现都是可以查出来的。缺点自然就是索引文件大大增加了。

实验三:一元分词中使用停用词

    既然索引文件增加,那么停用词来控制一些不必要的索引就显得很重要了。这个地方的设计有些奇怪,比如“玛瑙宝石很漂亮”,我把“很”加到停用词中,你搜索“宝石漂亮”是没有命中的,这里必须是“宝石#漂亮”(#表示任意的停用词)才能命中。初步推测就是他匹配的是把停用词的offset也考虑在内了。这里如果用英文的就没这个问题,因为英文两个词之间是天然的空白符,这就会变成AND或者OR的条件了。

实验四:一元分词中使用保留词

    在多元分词中会经常用到保留词,就是让一些专有词汇不要再被分词了。这里在一元分词中会把每个字当作一个词,这个时候再去与保留词比较时会没有结果,因此保留词的设置也没有任何意义。但是一元分词本身就天然支持任意连续字的匹配,其实这个功能相当于已经实现且不再需要配置。

Analysis中的发现:

    在进行分析的时候,最好就是用自带的Analysis工具了,选中verbose output 输出你将看到更详细的信息。这里你会发现下面Index Analyzer和Query Analyzer有时会有很多行,在verbose中就可以清晰的看出来几轮处理的差异。以Index阶段为例,其实就是先分词然后再利用过滤器处理,在默认的text类型中步骤如下:
  1. 第一步是StandardTokenizerFactory进行一元分词,这个很好理解;
  2. 第二步是StopFilterFactory进行停用词过滤,这个就是把停用词不进行索引;
  3. 第三步是WordDelimiterFilterFactory,这个里面有几个更细致的参数。splitOnCaseChange表示是否根据大小写切词,generateNumberParts表示是否对数字分块,catenateWords表示是否要是连续的词。
  4. 第四步是LowerCaseFilterFactory进行大小写转换;
  5. 第五步是KeywordMarkerFilterFactory根据专用词进行对不应该分词的内容进行合并;
  6. 第六步是PorterStemFilterFactory会把英文中的复数处理成单数。
  另外还可以设置SynonymFilterFactory,这是加上同义词的内容。还有更多的过滤器,详细可以查阅http://wiki.apache.org/solr/AnalyzersTokenizersTokenFilters