lucene学习之创建自定义排序
2015-05-06 18:25
323 查看
Lucene提供了一套强大的API来帮助我们实现自定义排序,本节我们使用一个距离搜索的例子来阐述:
其实核心是换一个comparator就成,而这个排序器用在哪里呢,如下所示:
其实核心是换一个comparator就成,而这个排序器用在哪里呢,如下所示:
package custom; import java.io.IOException; import org.apache.lucene.search.FieldComparator; import org.apache.lucene.search.FieldComparatorSource; public class DistanceComparatorSource extends FieldComparatorSource { private int x; private int y; public DistanceComparatorSource(int x,int y){ this.x = x; this.y = y; } @Override public FieldComparator<?> newComparator(String fieldname, int numHits, int sortPos, boolean reversed) throws IOException {//lucene所跟踪的队列 return new DistanceSourceLookupComparHor(fieldname, num` its,x,y); } } package custom; import java.io.IOException; import org.apache.lucene.index.BinaryDocValues; import org.apache.lucene.index.LeafReaderContext; import org.apache.lucene.search.SimpleFieldComparator; import org.apache.lucene.util.BytesRef; public class DistanceSourceLookupComparator extends SimpleFieldComparator<String> { private float[] values; private float top; private float bottom; private String fieldName; private int x; private int y; private BinaryDocValues binaryDocValues; public DistanceSourceLookupComparator(String fieldName, int numHits, int x, int y) { values = new float[numHits]; this.fieldName = fieldName; this.x = x; this.y = y; } @Override public int compare(int slot1, int slot2) { if (values[slot1] > values[slot2]) { return 1; } if (values[slot1] < values[slot2]) { return -1; } return 0; } private float getDistance(int doc) { BytesRef bytesRef = binaryDocValues.get(doc); String xy = bytesRef.utf8ToString(); String[] array = xy.split(","); int deltax = Integer.parseInt(array[0]) - x; int deltay = Integer.parseInt(array[1]) - y; float distance = (float) Math.sqrt(deltax * deltax + deltay * deltay); //System.out.println(distance); return distance; } @Override protected void doSetNextReader(LeafReaderContext context) throws IOException { binaryDocValues = context.reader().getBinaryDocValues(fieldName); } public void setBottom(int slot) { bottom = values[slot]; }//设置底部slot public int compareBottom(int doc) throws IOException {//与队列中命中结果评分最低的比较 float distance = getDistance(doc); if (bottom < distance) { return -1; } if (bottom > distance) { return 1; } return 0; } public int compareTop(int doc) throws IOException { float distance = getDistance(doc); if (top < distance) { return -1; } if (top > distance) { return 1; } return 0; } public void copy(int slot, int doc) throws IOException {//新的命中结果拷贝至队列中 values[slot] = getDistance(doc); } @Override public void setTopValue(String value) { top = Float.valueOf(value); } @Override public String value(int slot) {// return values[slot] + ""; } } package custom; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.document.BinaryDocValuesField; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.index.DirectoryReader; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; import org.apache.lucene.index.IndexWriterConfig.OpenMode; import org.apache.lucene.index.Term; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Query; import org.apache.lucene.search.ScoreDoc; import org.apache.lucene.search.Sort; import org.apache.lucene.search.SortField; import org.apache.lucene.search.TermQuery; import org.apache.lucene.search.TopFieldDocs; import org.apache.lucene.store.RAMDirectory; import org.apache.lucene.util.BytesRef; public class CustomSortTest { public static void main(String[] args) throws Exception { RAMDirectory directory = new RAMDirectory(); Analyzer analyzer = new StandardAnalyzer(); IndexWriterConfig indexWriterConfig = new IndexWriterConfig(analyzer); indexWriterConfig.setOpenMode(OpenMode.CREATE_OR_APPEND); IndexWriter indexWriter = new IndexWriter(directory, indexWriterConfig); addPoint(indexWriter, "El charro", "restaurant", 1, 2); addPoint(indexWriter, "Cafe Poca Cosa", "restaurant", 5, 9); addPoint(indexWriter, "Los Betos", "restaurant", 9, 6); addPoint(indexWriter, "Nico's Toco Shop", "restaurant", 3, 8); indexWriter.close(); IndexReader reader = DirectoryReader.open(directory); IndexSearcher searcher = new IndexSearcher(reader); Query query = new TermQuery(new Term("type","restaurant")); //使用重载后的排序类构造函数 Sort sort = new Sort(new SortField("location",new DistanceComparatorSource(10, 10))); TopFieldDocs topDocs = searcher.search(query, null, Integer.MAX_VALUE,sort,true,false); ScoreDoc[] docs = topDocs.scoreDocs; for(ScoreDoc doc : docs){ Document document = searcher.doc(doc.doc); System.out.println(document.get("name") + ":" + doc.score); } } private static void addPoint(IndexWriter writer,String name,String type,int x,int y) throws Exception{ Document document = new Document(); String xy = x + "," + y; document.add(new Field("name",name,Field.Store.YES,Field.Index.NOT_ANALYZED)); document.add(new Field("type",type,Field.Store.YES,Field.Index.NOT_ANALYZED)); document.add(new Field("location",xy,Field.Store.YES,Field.Index.NOT_ANALYZED)); document.add(new BinaryDocValuesField("location", new BytesRef(xy.getBytes()))); writer.addDocument(document); } }
相关文章推荐
- 一步一步跟我学习lucene(13)---lucene搜索之自定义排序的实现原理和编写自己的自定义排序工具
- 16、学习Lucene3.5索引之自定义排序
- Jmeter学习——创建自定义的Java Sampler
- Scott Mitchell 的ASP.NET 2.0数据教程之二十七:创建自定义排序用户界面
- 微信公众平台开发学习记录(2)————自定义菜单创建
- SQL学习之使用order by 按照指定顺序排序或自定义顺序排序
- [置顶] Lucene 4.10 + Mysql 5.5 创建数据库表索引(Lucene 学习序列1)
- Perl 字符串操作 以及 自定义排序学习笔记
- 关于学习MSDN中"创建自定义字段类型和字段控件"的一些心得跟问题。
- 一步一步跟我学习lucene(1)---lucene的IndexWriter对象创建和索引策略的选择
- lucene学习之搜索排序
- C#学习之自定义数组及其排序
- 创建自定义控件学习
- ASP.NET 2.0中的数据操作二十七:创建自定义排序用户界面
- Flex企业应用开发实践学习笔记(六)——使用ActionScript创建自定义组件
- 01_java Lucene学习——创建索引
- 自己学习中的知识点(5)---List<自定义类型> 按自定义类型中某个字段排序
- Java入门学习: Java对象自定义排序的实现
- [今日技术学习]利用ASP.NET 2.0创建自定义Web控件
- (学习Asp.net Ajax笔记一)使用 Microsoft AJAX Library 创建自定义客户端脚本之一