lucene综合使用
I.Sorting search results
在Lucene中有两种特别的类型是用来排序的:Score和Index order
要排序结果 可以使用IndexSearcher的重载serach函数,提供一个Sort参数.看个例子.SortingExample.java
01?package?lia.advsearching;02?03?import?org.apache.commons.lang.StringUtils;04?import?org.apache.lucene.document.Document;05?import?org.apache.lucene.index.Term;06?import?org.apache.lucene.search.Hits;07?import?org.apache.lucene.search.IndexSearcher;08?import?org.apache.lucene.search.Query;09?import?org.apache.lucene.search.RangeQuery;10?import?org.apache.lucene.search.Sort;11?import?org.apache.lucene.search.SortField;12?import?org.apache.lucene.store.Directory;13?import?org.apache.lucene.store.FSDirectory;14?15?import?java.io.IOException;16?import?java.text.DecimalFormat;17?18?public?class?SortingExample?{19???private?Directory?directory;20?21???public?SortingExample(Directory?directory)?{22?????this.directory?=?directory;23???}24?? // 显示搜索结果25???public?void?displayHits(Query?query,?Sort?sort)26???????throws?IOException?{27?????IndexSearcher?searcher?=?new?IndexSearcher(directory);28?29?????Hits?hits?=?searcher.search(query,?sort);? // 安sort 来排序搜索结果30?31?????System.out.println("\nResults?for:?"?+32?????????query.toString()?+?"?sorted?by?"?+?sort);? // 打印query 和sort33?34?????System.out.println(StringUtils.rightPad("Title",?30)?+?? // 使用StringUtils(来自Apache commons)打印结果35?????????StringUtils.rightPad("pubmonth",?10)?+36?????????StringUtils.center("id",?4)?+37?????????StringUtils.center("score",?15));38?39?????DecimalFormat?scoreFormatter?=?new?DecimalFormat("0.######");40?????for?(int?i?=?0;?i?<?hits.length();?i++)?{???????????????? // 打印结果41???????Document?doc?=?hits.doc(i);42???????System.out.println(43???????????StringUtils.rightPad(44???????????????StringUtils.abbreviate(doc.get("title"),?29),?30)?+45???????????StringUtils.rightPad(doc.get("pubmonth"),?10)?+46???????????StringUtils.center(""?+?hits.id(i),?4)?+47???????????StringUtils.leftPad(48???????????????scoreFormatter.format(hits.score(i)),?12));49???????System.out.println("???"?+?doc.get("category"));50?//??????System.out.println(searcher.explain(query,?hits.id(i)));51?????}52?53?????searcher.close();54???}55?56???public?static?void?main(String[]?args)?throws?Exception?{57?????Term?earliest?=?new?Term("pubmonth",?"190001");58?????Term?latest?=?new?Term("pubmonth",?"201012");59?????RangeQuery?allBooks?=?new?RangeQuery(earliest,?latest,?true);???? //? query60?61?????String?indexDir?=?System.getProperty("index.dir");? // index的目录62?63?????FSDirectory?directory?=64?????????FSDirectory.getDirectory(indexDir,?false);65?????SortingExample?example?=?new?SortingExample(directory);66?67?????example.displayHits(allBooks,?Sort.RELEVANCE);? // 使用Lucene默认的排序68?69?????example.displayHits(allBooks,?Sort.INDEXORDER);? // 根据IndexOrder排序70?71?????example.displayHits(allBooks,?new?Sort("category"));? // 根据category 排序72?73?????example.displayHits(allBooks,?new?Sort("pubmonth",?true));? // 根据pubmonth 排序74?75?????example.displayHits(allBooks,76?????????new?Sort(new?SortField[]{77???????????new?SortField("category"),78???????????SortField.FIELD_SCORE,79???????????new?SortField("pubmonth",?SortField.INT,?true)80?????????}));? /// 81?82?83?????example.displayHits(allBooks,?new?Sort(new?SortField[]?{SortField.FIELD_SCORE,?new?SortField("category")}));84???}85?}
当sort 参数是null ,new Sort(),和Sort.RELEVANCE 时,使用的是Lucene的默认排序(按照Relevance的递减排序), 默认搜索的结果如下:
先按照Score递减排序 如果Score相同则按照Docnum 递增排序.
If the order documents were indexed is relevant, you can use Sort.INDEXORDER.
下面是其输出结果:(安装ID来排序)
要利用Field排序,该field要满足第二章排序(参考我的Blog上的内容)的要求. 下面是使用category field的输出.
默认的field排序是按照自然排序,利用Sort的重载函数,提供一个reverse参数可以改变顺序.结果如下:
example.displayHits(allBooks, new Sort("pubmonth", true)); 提供了true参数.
还可以根据多个Field排序. 用法如下:
example.displayHits(allBooks,
new Sort(new SortField[]{
new SortField("category"),
SortField.FIELD_SCORE,
new SortField("pubmonth", SortField.INT, true)
}));
margin: 5pt 6