lucene4.7 之排序(四)

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


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

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

java

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


咱们再来看几个检索时须要用的方法数据库

 =========SortField类============
//field是排序字段type是排序类型
public SortField(String field, Type type);
//field是排序字段type是排序类型reverse是指定升序仍是降序
//reverse 为true是降序  false为升序
  public SortField(String field, Type type, boolean reverse)

  =========Sort类============
  public Sort();//Sort对象构造方法默认是按文档评分排序
  public Sort(SortField field);//排序的一个SortField
  public Sort(SortField... fields)//排序的多个SortField能够传入一个数组
 
  =========IndexSearche类r========
//query是查询的Query对象 filter是过滤  n返回的数量  sort是排序
search(Query query, Filter filter, int n, Sort sort) 
//doDocScores 为true状况下每一个命中的结果下都会被评分
//doMaxScore  为true状况下对最大分值的搜索结果进行评分
search(Query query, Filter filter, int n, Sort sort, boolean doDocScores, boolean doMaxScore)
1,在尚未进行一点排序前咱们先来看下索引里的内容,核心代码以下:
        TopDocs topDocs=searcher.search(new MatchAllDocsQuery(),10000);

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

   Sort sort=new Sort();//默认使用关联性评分
             TopDocs topDocs=searcher.search(new MatchAllDocsQuery(),10000,sort);

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

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

 Sort sort=new Sort(new SortField("date", Type.INT,true));//true为降序排列
             TopDocs topDocs=searcher.search(new MatchAllDocsQuery(),10000,sort);


4,按照价格升序排序,,核心代码和运行效果图以下:
性能

 Sort sort=new Sort(new SortField("price", Type.DOUBLE,false));//false为降序排列
             TopDocs topDocs=searcher.search(new MatchAllDocsQuery(),10000,sort);

5,多字段排序,按照日期降序的状况下,由于id为7和8的日期相同,因此咱们就新增一个排序字段按ename升序排列,,核心代码和运行效果图以下:
网站

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

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

    Sort sort=Sort.RELEVANCE;
            TopDocs topDocs=searcher.search(new TermQuery(new Term("bookname", "编程")),null,100,sort,true,true);

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

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

code

 SortField sortField = new SortField("value", SortField.Type.INT);
    sortField.setMissingValue(Integer.MAX_VALUE);
相关文章
相关标签/搜索