Lucene.net实现自定义排序笔记
在Lucene.net实现自定义排序,需要实现两个Lucene.Net.Search的两个接口:
public interface SortComparatorSource
{
ScoreDocComparator NewComparator(IndexReader reader , System.String fieldname) ;
}
public interface ScoreDocComparator
{
int Compare(ScoreDoc i , ScoreDoc j) ;
System.IComparable SortValue(ScoreDoc i) ;
int SortType() ;
}
涉及到的一个类:
public class ScoreDoc
{
public float score ;
public int doc ;
public ScoreDoc(int doc , float score)
{
this.doc = doc ;
this.score = score ;
}
}
Lucene.net 2.0包含的SortType有:
在Lucene.Net.Search.SortField里定义的:
public class SortField
{
public const int SCORE = 0 ; //相关度
public const int DOC = 1 ; //文挡号
public const int AUTO = 2 ; //自动识别
public const int STRING = 3 ; //字符型
public const int INT = 4 ; //int
public const int FLOAT = 5 ; //float
public const int CUSTOM = 9 ; //自定义
.....
}
少了DateTime,那就实现DateTime类型的自定义排序来测试下:
Lucene.Net.Search.ScoreDocComparator接口的实现类:
public class DateDocComparator : Lucene.Net.Search.ScoreDocComparator
{
private string fieldname = null;
private System.IComparable[] cachedValues ;
public DateDocComparator(System.IComparable[] cachedValues, string fieldname)
{
this.cachedValues = cachedValues;
this.fieldname = string.Intern(fieldname) ;
}
public int Compare(ScoreDoc i, ScoreDoc j)
{
return this.cachedValues[i.doc].CompareTo(this.cachedValues[j.doc]) ;
}
public System.IComparable SortValue(ScoreDoc i)
{
return this.cachedValues[i.doc] ;
}
public int SortType()
{
return Lucene.Net.Search.SortField.CUSTOM ;
}
}
Lucene.Net.Search.SortComparatorSource接口的实现类:
public class DateSortComparatorSource : Lucene.Net.Search.SortComparatorSource
{
public ScoreDocComparator NewComparator(Lucene.Net.Index.IndexReader reader, System.String field)
{
return new DateDocComparator(GetCustom(reader, field), field);
}
protected virtual System.IComparable[] GetCustom(Lucene.Net.Index.IndexReader reader, System.String field)
{
System.IComparable[] retArray = new System.IComparable[reader.MaxDoc()];
Lucene.Net.Index.TermDocs termDocs = reader.TermDocs();
Lucene.Net.Index.TermEnum termEnum = reader.Terms(new Lucene.Net.Index.Term(field, ""));
try
{
do
{
Lucene.Net.Index.Term term = termEnum.Term();
if (term == null || term.Field() != field)
break;
System.IComparable termval = Lucene.Net.Documents.DateTools.StringToDate(term.Text()) ;
termDocs.Seek(termEnum);
while (termDocs.Next())
{
retArray[termDocs.Doc()] = termval;
}
}
while (termEnum.Next());
}
finally
{
termDocs.Close();
termEnum.Close();
}
return retArray;
}
}
使用:
Sort sort = new Sort(new SortField("datecreated",new DateSortComparatorSource(),true)) ;