欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Lucene 分词解读(二)--Analyzer 博客分类: 系统架构javalucene  

程序员文章站 2024-03-23 17:21:46
...
Lucene中的Analyzer

为了更好地搜索中文,在Lucene中通过WhitespaceTokenizer、WordDelimiter Filter、LowercaseFilter处理英文字符串。

Lucene中的StandardAnalyzer对于中文采用了单字切分的方式,这样的结果是单字匹配,如搜索"上海",可能会返回和"海上"有关的结果。

CJKAnalyzer采用了二元覆盖的方式实现。小规模搜索网站可以采用二元覆盖的方法,这样可以解决单字搜索"上海"和"海上"混淆的问题。采用中文分词的方法适用于中大规模的搜索引擎。猎兔搜索提供了一个基于Lucene接口的Java版中文分词系统。

可以对不同的索引列使用不同的Analyzer来切分。例如可以对公司名采用CompanyAnalyzer来分析;对地址列采用AddressAnalyzer来分析。这样可以通过更细分化的切分方式来实现更准确合适的切分效果。

例如把"唐山聚源食品有限公司"拆分成如表4-1所示的结果。

表4-1  公司名拆分结果表
词    开始位置    结束位置    标注类型
唐山  0  2  City
聚源  2  4  KeyWord
食品  4  6  Feature
有限公司   6  10  Function

这里的开始位置和结束位置是指词在文本中的位置信息,也叫做偏移量。例如"唐山"这个词在"唐山聚源食品有限公司"中的位置是0-2。OffsetAttribute属性保存了词的位置信息;TypeAttribute属性保存了词的类型信息。

专门用来处理公司名的CompanyAnalyzer实现代码如下所示:
   
引用
public class CompanyAnalyzer extends  
       Analyzer {  
        public TokenStream tokenStream  
           (String fieldName, Reader reader) { 
            //调用ComTokenizer切分公司名 
            TokenStream stream = new          
    ComTokenizer(reader); 
            //调用ComFilter后续加工 
            stream = new ComFilter          (stream); 
            return stream; 
        } 
    } 


对不同的数据写了不同用途的分析器,需要在同一个索引中针对不同的索引列使用。一般情况下只使用一个分析器。为了对不同的索引列使用不同的分析器,可以使用PerFieldAnalyzerWrapper。在PerFieldAnalyzerWrapper中,可以指定一个默认的分析器,也可以通过addAnalyzer方法对不同的列使用不同的分析器,例如:
  
引用
PerFieldAnalyzerWrapper aWrapper = 
          new PerFieldAnalyzerWrapper(new CnAnalyzer()); 
       aWrapper.addAnalyzer("address", new AddAnalyzer()); 
       aWrapper.addAnalyzer("companyName",
    new CompanyAnalyzer()); 


在这个例子中,将对所有的列使用CnAnalyzer,除了地址列使用AddAnalyzer且公司名称列使用CompanyAnalyzer。像其他分析器一样,PerFieldAnalyzerWrapper可以在索引或者查询解析阶段使用。