如何在Lucene.Net中一个Document使用不同的分词(一)

这是在博客园Lucene.Net小组看到的一个问题。呵呵,尝试用以下方法解决。
说明:代码没有经过测试。


在Lucene.Net中一个Document对象创建并不涉及到分词,分词是跟IndexWriter相关的。

以类库自带的StandardAnalyzer分词举例,创建一个索引的过程如下

/* 实例化写入 */
IndexWriter writer 
= new IndexWriter(new Lucene.Net.Analysis.Standard.StandardAnalyzer(),true);
/* 建立文档 */
Document doc 
= new Document();
doc.Add(
new Field("id""123", Field.Store.YES, Field.Index.TOKENIZED));
doc.Add(
new Field("title""这个是标题", Field.Store.YES, Field.Index.TOKENIZED));
doc.Add(
new Field("content""这个是内容", Field.Store.YES, Field.Index.TOKENIZED));
/*  写入文档 */
writer.AddDocument(doc);
/* 优化索引结构 */
writer.Optimize();
/* 关闭写入 */
writer.Close();

在这样的代码里想一个文档不同字段使用不同分词是不可能的。如果要让每个字段使用不同分词,那么当然是给每个字段加上分词器属性。

先找到Lucene.Net的Field类,发现Field类的字段是继承自AbstractField父类的。在AbstractField先加上
protected internal Analysis.Analyzer analyzer;

然后增加一个构造函数:
        protected internal AbstractField(string name, Field.Store store, Field.Index index, Field.TermVector termVector, Analysis.Analyzer analyzer)
            : 
this(name, store, index, termVector)
        {
            
this.analyzer = analyzer;
        }

在Field类增加构造函数:
        public Field(System.String name, System.String value_Renamed, Store store, Index index, TermVector termVector, Analysis.Analyzer analyzer)
            : 
base(value_Renamed, store, index, termVector, analyzer)
        {

        }


在接口Fieldable中增加方法GetAnalyzer;
Analysis.Analyzer GetAnalyzer();


并且在AbstractField类中实现GetAnalyzer方法:

        public virtual Analysis.Analyzer GetAnalyzer()
        {
            
return this.analyzer;
        }

修改DocumentWriter类的 179行 ,如果因为版本不一样不在179行,请查找
“TokenStream stream = analyzer.TokenStream(fieldName, reader);”

然后换成

TokenStream stream = field.GetAnalyzer().TokenStream(fieldName, reader);

OK,写入的部分搞定了,读取的部分明天再弄。

现在就可以这么用了:

/* 实例化写入 */
IndexWriter writer 
= new IndexWriter(new Lucene.Net.Analysis.Standard.StandardAnalyzer(),true);
/* 建立文档 */
Document doc 
= new Document();
doc.Add(
new Field("id""123", Field.Store.YES, Field.Index.TOKENIZED, Field.TermVector.NO, new Lucene.Net.Analysis.KeywordAnalyzer()));
doc.Add(
new Field("title""这个是标题", Field.Store.YES, Field.Index.TOKENIZED, Field.TermVector.NO, new Lucene.Net.Analysis.Standard.StandardAnalyzer()));
doc.Add(
new Field("content","这个是内容", Field.Store.YES, Field.Index.TOKENIZED, Field.TermVector.NO, new Lucene.Net.Analysis.SimpleAnalyzer()));
/*  写入文档 */
writer.AddDocument(doc);
/* 优化索引结构 */
writer.Optimize();
/* 关闭写入 */
writer.Close();

当然,这个时候,IndexWriter 的分词器实际上是无用的,也可以判定Field给定的分词器是否为null,然后用IndexWriter 的作为默认分词器。

by yurow @ http://www.cnblogs.com/birdshover/

更新第二部分地址:如何在Lucene.Net中一个Document使用不同的分词(二)
posted @ 2008-07-21 21:01  Birdshover  阅读(3218)  评论(10编辑  收藏  举报