说明:代码没有经过测试。
在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();
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;
}
: 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)
{
}
: base (value_Renamed, store, index, termVector, analyzer)
{
}
在接口Fieldable中增加方法GetAnalyzer;
Analysis.Analyzer GetAnalyzer();
并且在AbstractField类中实现GetAnalyzer方法:
public
virtual
Analysis.Analyzer GetAnalyzer()
{
return this .analyzer;
}
{
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 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使用不同的分词(二)