自定义的Lucene排序

从1.4版本开始,Lucene开始支持自定义的结果排序,而在之前,结果只能按照评分结果倒序排列(desc)。

    通常,在查询时我们使用IndexSearcher的search(Query query)方法,这个方法默认返回的结果是按照评分结果倒序排列.要实现自定义排序,则应该使用search方法的overload版本search(Query query,Sort sort).
    public class SortingExample {
        private Directory directory;
        public SortingExample(Directory directory) {
            this.directory = directory;
        }
        public void displayHits(Query query, Sort sort)
            throws IOException {
            IndexSearcher searcher = new IndexSearcher(directory);
            Hits hits = searcher.search(query, sort);
            System.out.println("\nResults for: " +query.toString() + " sorted by " + sort);
            System.out.println(StringUtils.rightPad("Title", 30) + StringUtils.rightPad("pubmonth", 10) + StringUtils.center("id", 4) +
StringUtils.center("score", 15));
            DecimalFormat scoreFormatter = new DecimalFormat("0.######");
            for (int i = 0; i < hits.length(); i++) {
                Document doc = hits.doc(i);
                System.out.println(
StringUtils.rightPad
StringUtils.abbreviate(doc.get("title"), 29), 30) +
StringUtils.rightPad(doc.get("pubmonth"), 10) +
StringUtils.center("" + hits.id(i), 4) +
StringUtils.leftPad(
scoreFormatter.format(hits.score(i)), 12));
                System.out.println(" " + doc.get("category"));
                // System.out.println(searcher.explain(query, hits.id(i)));
           }
           searcher.close();
        }
    }
    不用理会具体的输出的细节.
    通过在查询时传入自定义的Sort对象,我们就可以实现自定义的排序规则.
 
      首先,我们应该有一个概念,在Lucene的内置排序方法中,升降序规则默认都是natural ording,即在Sorting by relevance中默认desc,在其他排序中则是asc。
    1.Sorting by relevance,中文可以叫"适当的排序"?好象有点别扭,呵呵.这也是Lucene的默认排序,即按评分结果倒序排列.
      以下几种search方法都是实现的同样的效果:
      search(Query query,null),search(Query query,Sort.RELEVANCE),search(Query query,new Sort())
      结果首先按照评分结果desc排序,如果评分相同,则按照document id asc排序,其中,document id是document在索引时的先后顺序。
    2.Sorting by index order,按照索引的先后顺序asc排列。
    3.Sorting by a field,按field排序。field是在索引时建立的单元。这里需要注意的一点是,如果想按照field来排序,需要几个规则:首先,这个field必须是indexed and not tokenized,就是需要索引,但是不能分词,例如Field.KEYWORD()方法;这个field必须可以转换成Integers,Floats,Strings,可以在用Field生成Sort对象的时候指定field的类型。
   
    正像前边提到的,在lucene中的默认结果升降序规则是natural ording,当然我们也可以自己指定排序的升降序规则。
    首先,我们指定结果按照某一个field来desc排序(如果不指定,field是按照asc排序)。例如,IndexSearcher.search(Query query,new Sort("date",true)),这里参数true的作用既是使得结果按照date field按照降序排列,这样我们就可以将日期最近的结果排列到最前面。
    通常,排序规则不会这么简单。例如,在某一个图书查询系统中,我们需要的排序规则是,首先按照图书的目录排序,然后同一目录的图书按照评分结果排序,评分结果相同并且目录相同的图书按照出版日期降序排列,代码片段如下:
    indexSearcher.search(Query query,new Sort(
        new SortField[]{
            new SortField("category"),
            SortField.FIELD_SCORE,
            new SortField("pubmonth", SortField.INT, true)
        }
    )
    这里,我们指定了一个SortField的数组,图书目录按照字典升序排列,然后目录相同的按照评分结果降序排列,最后按照出版日期降序排列。
    其实,在lucene内部自动维护了一个排序的数组,只是在这个例子中,我们显示的指定了排序的规则而已。

    排序对查询性能的影响。排序需要额外的资源消耗,更多的内存消耗。lucene只是缓存实际需要排序的field。即使如此,如果需要自定义排序,仍然需要仔细的规划,记住,按照一个String来排序将花费最大的资源。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值