lucene排序

标签: lucene 排序 | 发表时间:2014-02-10 02:53 | 作者:summer85
出处:http://www.iteye.com

原文 http://qindongliang1922.iteye.com/blog/1924608 

 

排序是对于全文检索来言是一个必不可少的功能,在实际运用中,排序功能能在某些时候给我们带来很大的方便,比如在淘宝,京东等一些电商网站我们可能通过排序来快速找到价格最便宜的商品,或者通过排序来找到评论数最高或卖的最好的商品,再比如在Iteye里的博客栏里,每天都会以降序的方式,来显示出最新发出的几篇博客,有了排序,我们就能在某些时候很方便快速的得到某些有效信息,所以说排序功能,无处不在 ^_^。 


那么,本篇散仙就来看下我们在Lucene中怎么使用其丰富的排序功能。 

在这之前,我们先来熟悉下lucene中排序的基本知识,在默认情况下,Lucene使用的是以关联性降序的方式为默认的排序方式,这样可以使得我们搜索的结果通常是最优的,因为它会尽可能的使得首先出现的几个结果是与我们搜索的内容最相关,而不需要我们翻页寻找我们最想要的内容,这一点是与数据库相比,是全文检索一个很大的优点。当然,在实际开发中我们也需要根据业务的实际情况来给我们的客户提供多种不同的排序方式。我们先来看下在Lucene中比较特殊的两种基本的排序方式 


Sort里的属性 SortField里的属性 含义
Sort.INDEXORDER SortField.FIELD_DOC 按照索引的顺序进行排序
Sort.RELEVANCE SortField.FIELD_SCORE 按照关联性评分进行排序



我们再来看几个检索时需要用的方法 

Java代码   收藏代码
  1.  =========SortField类============  
  2. //field是排序字段type是排序类型  
  3. public SortField(String field, Type type);  
  4. //field是排序字段type是排序类型reverse是指定升序还是降序  
  5. //reverse 为true是降序  false为升序  
  6.   public SortField(String field, Type type, boolean reverse)  
  7.   
  8.   =========Sort类============  
  9.   public Sort();//Sort对象构造方法默认是按文档评分排序  
  10.   public Sort(SortField field);//排序的一个SortField  
  11.   public Sort(SortField... fields)//排序的多个SortField可以传入一个数组  
  12.    
  13.   =========IndexSearche类r========  
  14. //query是查询的Query对象 filter是过滤  n返回的数量  sort是排序  
  15. search(Query query, Filter filter, int n, Sort sort)   
  16. //doDocScores 为true情况下每个命中的结果下都会被评分  
  17. //doMaxScore  为true情况下对最大分值的搜索结果进行评分  
  18. search(Query query, Filter filter, int n, Sort sort, boolean doDocScores, boolean doMaxScore)   
  19.    


1,在还没有进行一点排序前我们先来看下索引里的内容,核心代码如下: 

Java代码   收藏代码
  1. TopDocs topDocs=searcher.search(new MatchAllDocsQuery(),10000);       



2,使用默认的关联性评分后,核心代码和运行效果图如下: 

Java代码   收藏代码
  1. Sort sort=new Sort();//默认使用关联性评分  
  2.     TopDocs topDocs=searcher.search(new MatchAllDocsQuery(),10000,sort);  





关于上图中乱码字符原因是因为默认排序情况下lucene是不会对搜索结果进行评分操作的,因为评分操作会降低性能,所以关于score的那一列返回的是NAN的字符串,出于格式的需要,散仙在用DecimalFormat类给其评分结果保留2位小数时,因为是一个特殊字符,所以就出现了上图情况。 

3,按照日期降序排序,,核心代码和运行效果图如下: 

Java代码   收藏代码
  1. Sort sort=new Sort(new SortField("date", Type.INT,true));//true为降序排列  
  2.          TopDocs topDocs=searcher.search(new MatchAllDocsQuery(),10000,sort);  




3,按照价格升序排序,,核心代码和运行效果图如下: 

Java代码   收藏代码
  1. Sort sort=new Sort(new SortField("price", Type.DOUBLE,false));//false为降序排列  
  2.          TopDocs topDocs=searcher.search(new MatchAllDocsQuery(),10000,sort);  




4,多字段排序,按照日期降序的情况下,因为id为7和8的日期相同,所以我们就新增一个排序字段按ename升序排列,,核心代码和运行效果图如下: 

Java代码   收藏代码
  1. // Sort sort=new Sort(new SortField("date", Type.INT, true),new SortField("ename", Type.STRING, false));  
  2.         //这两段代码效果一样  
  3.         Sort sort=new Sort(new SortField[]{new SortField("date", Type.INT, true),new SortField("ename", Type.STRING, false)});  
  4.          TopDocs topDocs=searcher.search(new MatchAllDocsQuery(),10000,sort);  




5,带评分的排序,注意后面两个布尔类型的变量可以控制是否评分,特别是在没有要求需要打分时,建议别开启,大数量时对性能影响较大,检索“编程”得到的结果,默认按评分降序排序,核心代码和运行效果图如下: 

Java代码   收藏代码
  1. Sort sort=Sort.RELEVANCE;  
  2.   TopDocs topDocs=searcher.search(new TermQuery(new Term("bookname", "编程")),null,100,sort,true,true);  




上面的编程,编程因为在切分时编程的tf出现了2次,所以在查询时有较高的得分,所以排在首位。 

6,注意几点 
(1)排序对一个文档里什么域都没存储,使用字符串排序会排在首位 
(2)排序对一个文档里什么域都没存储,使用数字类型排序会默认给其赋值为0进行排序 
(3)我们可以对数字类型的null值的文档进行代码控制,可以将其设置为最大,所以将会排在最后面,代码如下 

Java代码   收藏代码
  1. SortField sortField = new SortField("value", SortField.Type.INT);  
  2.    sortField.setMissingValue(Integer.MAX_VALUE);  


已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



相关 [lucene 排序] 推荐:

lucene排序

- - 开源软件 - ITeye博客
排序是对于全文检索来言是一个必不可少的功能,在实际运用中,排序功能能在某些时候给我们带来很大的方便,比如在淘宝,京东等一些电商网站我们可能通过排序来快速找到价格最便宜的商品,或者通过排序来找到评论数最高或卖的最好的商品,再比如在Iteye里的博客栏里,每天都会以降序的方式,来显示出最新发出的几篇博客,有了排序,我们就能在某些时候很方便快速的得到某些有效信息,所以说排序功能,无处不在 ^_^.

[原]Lucene系列-facet

- - 文武天下
facet:面、切面、方面. 个人理解就是维度,在满足query的前提下,观察结果在各维度上的分布(一个维度下各子类的数目). 如jd上搜“手机”,得到4009个商品. 其中品牌、网络、价格就是商品的维度(facet),点击某个品牌或者网络,获取更细分的结果. 点击品牌小米,获得小米手机的结果,显示27个.

[原]Lucene系列-FieldCache

- - 文武天下
域缓存,加载所有文档中某个特定域的值到内存,便于随机存取该域值. 当用户需要访问各文档中某个域的值时,IndexSearcher.doc(docId)获得Document的所有域值,但访问速度比较慢,而且只能获得Stored域的值. FieldCache能获得域值数组,根据docId random access域值.

Lucene 使用教程

- - 行业应用 - ITeye博客
1 lucene简介 . 1.1 什么是lucene . Lucene是一个全文搜索框架,而不是应用产品. 因此它并不像 http://www.baidu.com/ 或者google Desktop那么拿来就能用,它只是提供了一种工具让你能实现这些产品. 1.2 lucene能做什么 . 要回答这个问题,先要了解lucene的本质.

Lucene 4.x 之 IndexReader

- - zzm
在Lucene 3.x时代,《Lucene In Action》是一本相当不错的参考书,书中详细介绍了Lucene各种高级使用技术,对于开发者来说非常实用. 但是近期Lucene升级到了4.x版本,在性能等各方面有了很大的提高,值得在新项目中使用. 然而Lucene 4.x中的API相比3.x来说有了很大的改变,《Lucene In Action》中的很多内容都已经过时了,并且由于4.x推出的时间不长,还没有比较好的文档来对用法进行说明,这个系列文章就是想记录下自己使用Lucene 4.x的经验体会,供大家参考使用.

文章: 集成Lucene和HBase

- - InfoQ cn
在所有先进的应用程序中,不管是购物站点还是社交网络乃至风景名胜站点,搜索都扮演着关键的角色. Lucene搜索程序库事实上已经成为实现搜索引擎的标准. 苹果、IBM、Attlassian(Jira)、Wolfram以及很多大家喜欢的公司【1】都使用了这种技术. 因此,大家对任何能够提升Lucene的可伸缩性和性能的实现都很感兴趣.

Solr\Lucene优劣势分析

- - 淘宝网综合业务平台团队博客
最早lucene2.4以及以前,追溯到2008年前后,lucene刚刚引起大家的关注,到后来Nutch. 、solr的出现,lucene变得更加热. Nutch、Solr的发展,极大推动了lucene的升级. 对于一些接触过搜索,使用过lucene、solr的人来说,一般都会感觉lucene、solr很牛逼.

lucene Direction类 和 term查询

- - 开源软件 - ITeye博客
一 、 Directory介绍. 1、使用FSDirectory.open(java.io.File)方法,会根据当前的运行环境打开一个最合理的基于File的Directory. SimpleFSDirectory : 使用RandomAccessFile类访问文件,但是在并发上面效率不是很高. NIOFSDirectory : 使用java.nio.FileChannel,能够提高并发访问效率.