计算基点与索引库中每个地理位置的距离,按距离大小排序。基点为(0,0),计算从(0,0)到地图中各个地方的距离,然后依此排序,但地方进行了分类,包括restaurant、school、shop。这些类放在一个type域中,
1、通过实现SortComparatorSource接口来完成自定义排序。对每个类分别完成计算基点到这些类的地方的距离
public class DistanceComparatorSource implementsSortComparatorSource{
private int x;
private int y;
publicDistanceComparatorSource(int x,int y){
this.x=x;
this.y=y;
}
//SortComparatorSource唯一需要实现的方法是newComparator
publicScoreDocComparator newComparator(IndexReader reader,Stringfieldname)
throwsIOException
{
//返回一个自定义比较器
return newDistanceScoreDocLookupComparator(reader,fieldname,x,y);
}
//lucene会负责对ScoreDocComparator对象存储,每个基点对应于一个比较器
privatestatic class DistanceScoreDocLookupComparator implements ScoreDocComparator{
final TermEnum enumerator=reader.terms(newTerm(filedname,""));//定义一个项枚举器
//,对reader的所有文档的坐标项进行迭代
distances=newfloat[reader.maxDoc()];//定义该基点与所有文档坐标项的距离数组
if (distances.length>0) {//保证至少有一个文档
TermDocstermDocs=reader.termDocs();//取出所有文档的项
try{
if (enumerator.term()==null){
throw new RuntimeException("no terms infield"+fieldname);
}
do{//开始计算距离数组
Term term=enumerator.term();
if (term.field()!=fieldname) break;
termDocs.seek(enumeartor);
while (termDocs.next()){
String[] xy=term.text().split(",");//从项值得出坐标
//计算,存储基点与该项坐标之间的距离
intdeltax=Integer.parseInt(xy[0])-x;
int deltay=Integer.parseInt(xy[1])-y;
distances[termDocs.doc()]=
(float) Math.sqrt(deltax*deltax_delay*deltay);
}//完成包含当前项的文档的遍历完成距离计算
}while(enumerator.next());//对指定域内的所有项进行遍历,笔者认为fieldname
//是指query中指定的域名,即这些地点的类型,因为地方可能至少要几种类
//型,所以要对域内的项进行遍历。
}fianlly{
termDocs.close();
}
}
}
public intcompare(){//调用完成排序
if (distances[i.doc]<distances[j.doc]) return-1;
if (distances[i.doc]>distances[j.doc]) return1;
return0;
}
publicComparable sortValue(ScoreDoc i){//输出确切的实际距离值
returnnew Float(distances[i.doc]);
}
public intsortType(){
return SortField.FLOAT;
}
}
public String toString(){
return "distance from("x","+y+")";
}
2、我们为每个地点都指定了三个域,即一个地名,一个用X和Y坐标表示的位置。
public class DistanceSortingTest extends tetstcase{
privateRAMDirectory directory;
privateIndexSearcher searcher;
privateQueryquery;
protectedvoid setUp() throws Exception{
directory=new RAMDirectory();
IndexWriter writer=new IndexWriter(directory,newWhitespaceAnalyzer(),true);
addPoint(writer,"E1 Charro","restaurant",1,2);
addPoint(writer,"cafe poca cosa","restaurant",5,9);
addPoint(writer,"os betos","restaurant",9,6);
addPoint(writer,"nico's tacoshop","restaurant",3,8);
writer.close();
searcher=newIndexSearcher(directory);
query=new TermQuery(new Term("type","restaurant"));
}
privatevoid addPoint(IndexWriter writer,String name,String type,int x,inty)
throws IOExceptoin{
Document doc=new Document();
doc.add(Field.Keyword("name",name));
doc.add(Field.Keyword("type",type));
doc.add(Field.Keyword("location",x+","+y));
}
}
下面进行测试
Sort sort=new Sort(newSortField("location",new DistanceComparatorSource(0,0)));
Hits hits=searcher.search(query,sort);
3、访问自定义排序的值
使用IndexSearcher的重载的search方法:
pulbic TopFieldDocs search(Query query,Filter filter,final intnDocs,Sort sort)
1)TopFieldDocs类中包括了HIts对象的总数,用来排序的SortField数组、FieldDoc对象的集合。FieldDoc封装了已经计算出来的原始评分、文档ID及Comparables集合,Comparable的值被每个SortField对象调用。
2)如果没有使用与排序相关的类,lucene为我们提供了类似的底层API,返回一个包含ScoreDoc对象的TopDocs对象。
3)
Sort sort=new Sort(newSortField("location",new DistanceComparatorSource(0,0)));
//指定返回的hit对象上限为3
TopFieldDocs docs=searcher.search(query,null,3,sort);
//hits对象的总数
assertEquals(4,docs.totalHits);//总数为4,因为要对所有hits进行评估找出3个最优的命中结果
assertEquals(3,docs.scoreDocs.length);//返回文档总数
FieldDoc fieldDoc=(FieldDoc)docs.scoreDocs[0];//获得排序值
assertEquals("(10,10)->(9,6)=sqrt(17)",newFloat(Math.sqrt(17)),fieldDoc.fields[0]);//断言距离最近的餐厅
Documentdocument=searcher.doc(fieldDoc.doc);//获得实际的文档
分享到:
相关推荐
因此,了解如何在 Lucene 中实现自定义排序是非常关键的。在这个话题中,我们将深入探讨如何根据特定的业务需求对搜索结果进行定制排序。 首先,我们要明白 Lucene 默认的排序机制。默认情况下,Lucene 搜索结果是...
Lucene提供了多种内置分析器,如StandardAnalyzer,用户也可以自定义分析器以适应特定的语言环境。 3. 索引(Index):索引是Lucene的核心,通过索引,Lucene能够快速定位到相关文档。IndexWriter类用于创建和更新...
6. **扩展性和定制化**:Lucene 是一个高度模块化的框架,允许开发者根据需求自定义分词器、查询解析器、评分函数等。此外,还可以通过插件机制添加新的功能或优化现有行为。 在压缩包中的"lucene-5.0.0"文件夹下,...
Pinyin4j是一个Java库,主要用于将汉字转换为拼音,这对于进行基于拼音的搜索和排序非常有用。pinyinAnalyzer是Lucene的一个分析器,它利用了Pinyin4j的功能,能够将输入的中文文本分词并转化为拼音形式,以便于...
在2.0.0版中,Lucene对分词器(Analyzer)进行了改进,支持自定义分词规则,以适应不同语言和领域的搜索需求。分词器将文本分解为独立的搜索单元,是影响搜索准确性和效率的关键因素。 除了核心功能,Lucene还提供...
描述中提到的《开发自己的搜索引擎》第二版,是一本可能教导如何利用Lucene创建自定义搜索引擎的书籍。配套的Lucene-jar包是读者在实践中需要用到的资源,这里提供的是2.0.0版本的jar文件。作者保证了这个压缩包的...
7. **高级功能**:Lucene还包括多线程支持、近实时搜索、自定义排序、过滤器(`Filter`)和拦截器(`Collector`)等高级特性,允许开发者进行更复杂的检索策略设计。 8. **扩展性**:Lucene本身只是一个库,开发者...
- 查询索引:使用IndexReader打开索引,创建IndexSearcher,构造Query,执行search方法获取匹配的Documents。 - 结果处理:对搜索结果进行迭代,获取高分Document并展示相关信息。 6. **新特性与改进**: - ...
Lucene提供多种预定义的分词器,如StandardAnalyzer,也可以自定义分词规则。 5. **搜索(Search)**:用户提交查询后,Lucene会使用查询解析器解析输入,生成查询对象,然后与索引进行匹配,返回最相关的文档。 6...
- **创建索引**:使用`IndexWriter`类创建和更新索引,添加`Document`对象并调用`addDocument`方法。 - **搜索索引**:通过`IndexSearcher`类执行查询,`Query`对象表示用户输入的查询条件,`TopDocs`返回匹配文档...
Lucene提供了多种预定义的分析器,如StandardAnalyzer,同时也允许自定义分析器以满足特定的语言或领域需求。 3. **查询解析**:用户输入的查询字符串经过查询解析器转换成可以执行的查询对象。Lucene支持丰富的...
- 可以实现自定义的排序策略,如基于时间、地理位置等。 总结,Lucene 5.3.1不仅是一个强大的全文检索工具,其源代码更是理解搜索引擎工作原理和优化技巧的宝贵资源。通过深入研究,开发者能够创建出更加高效、...
- **结果排序**:Lucene支持基于相关性的排名,通过ScoreDoc对搜索结果进行排序。 4. **Lucene的应用场景** - **网站搜索**:很多网站使用Lucene作为其内部搜索的后端,提供快速准确的站内搜索服务。 - **信息...
本文将深入探讨“Lucene5学习之自定义排序”这一主题,帮助你理解如何在Lucene5中实现自定义的排序规则。 首先,Lucene的核心功能之一就是提供高效的全文检索能力,但默认的搜索结果排序通常是基于相关度得分...
本篇将深入探讨Lucene 3.0.0版本的核心特性、设计理念以及使用方法。 一、Lucene概述 1.1 Lucene的基本概念 Lucene是一个纯Java库,用于索引和搜索大量文本数据。它提供了完整的搜索功能,包括分词、建立倒排索引...
结合以上文件,我们可以看到Lucene-2.0的学习不仅需要理解基本的索引构建和搜索原理,还需要掌握如何自定义排序规则和分析器以满足特定需求。此外,通过阅读和分析这些源码,开发者还可以深入理解Lucene的内部工作...
同时,Sort类则支持对结果进行定制化的排序,包括基于评分、字段值或自定义比较器的排序。 4. **高亮显示**: Lucene 提供了Highlighter组件,可以在搜索结果中高亮显示匹配的关键词,提升用户体验。4.6.1版文档会...
10. **性能调优**:Lucene提供了多种配置选项和策略,如批量添加文档、使用 compound 文件、设置缓存大小等,开发者可以根据具体应用场景进行调优。 以上是对Apache Lucene 4.10.3版本的一些核心知识点的介绍。这个...
3. **分词处理**:内置分词器,可处理多种语言的文本,支持自定义分词策略。 4. **排序与评分**:通过TF-IDF等算法,对搜索结果进行评分和排序,确保最相关的文档优先展示。 5. **高亮显示**:可以将搜索关键词在...
本文将详细介绍“lucene所有的jar包”,特别是其中的“my的jar”和“ik的jar包”,以及它们在Lucene 4.9.0版本中的作用和使用方法。 一、Lucene简介 Lucene是Apache软件基金会的一个开放源代码项目,它提供了一个...