Lucene排序以及自定义排序

现在开发搜索系统,使用的是开源界比较推崇的Lucene,版本是Maven库上面的3.5,这个版本里面有很多方法都不建议使用了。所以代码创建的方式有那么点变化,我使用的分词器是IkAnalyzer。Lucene全文检索的功能是很强大的,我们在做电子商务系统的时候肯定是会遇到排序的问题,比如销量,比如价格等等,为了方便客户我们便需要Lucene的排序功能,其实Lucene中的排序很简单也很方便,我们在创建搜索器的时候增加一个Sort 就行了,Sort的构造函数需要SortField,具体大家可以去参考Lucene的源代码,我下面写了一个简单的例子来演示怎么使用。代码如下:

Java代码 复制代码  收藏代码
  1. import java.io.IOException;   
  2. import java.util.Locale;   
  3. import org.apache.lucene.analysis.Analyzer;   
  4. import org.apache.lucene.document.Document;   
  5. import org.apache.lucene.document.Field;   
  6. import org.apache.lucene.document.Field.Index;   
  7. import org.apache.lucene.document.Field.Store;   
  8. import org.apache.lucene.index.IndexReader;   
  9. import org.apache.lucene.index.IndexWriter;   
  10. import org.apache.lucene.index.IndexWriterConfig;   
  11. import org.apache.lucene.search.FieldComparator;   
  12. import org.apache.lucene.search.FieldComparatorSource;   
  13. import org.apache.lucene.search.IndexSearcher;   
  14. import org.apache.lucene.search.Query;   
  15. import org.apache.lucene.search.ScoreDoc;   
  16. import org.apache.lucene.search.Sort;   
  17. import org.apache.lucene.search.SortField;   
  18. import org.apache.lucene.search.TopDocs;   
  19. import org.apache.lucene.store.RAMDirectory;   
  20. import org.apache.lucene.util.Version;   
  21. import org.junit.Test;   
  22. import org.wltea.analyzer.lucene.IKAnalyzer;   
  23. import org.wltea.analyzer.lucene.IKQueryParser;   
  24. import org.wltea.analyzer.lucene.IKSimilarity;   
  25. public class LuceneSortTest {   
  26.     /**  
  27.      * Lucene排序查询  
  28.      */  
  29.     @Test  
  30.     public void testSort() throws Exception{   
  31.         String name = "name";   
  32.         String field = "price";   
  33.         String names[] = {"衣服","睡衣","漂亮衣服","好看衣服","男士衣服","女士衣服"};   
  34.         double price[] = {12.0,13.0,8.8,9.6,7.5,12.1};   
  35.         RAMDirectory dir = new RAMDirectory();   
  36.         Analyzer analyzer = new IKAnalyzer();   
  37.         IndexWriterConfig cfg = new IndexWriterConfig(Version.LUCENE_35, analyzer);   
  38.         IndexWriter writer = new IndexWriter(dir, cfg);   
  39.         for (int i=0;i<names.length;i++) {   
  40.             Document doc = new Document();   
  41.             doc.add(new Field(name, names[i], Store.YES, Index.ANALYZED));   
  42.             doc.add(new Field(field, String.valueOf(price[i]), Store.YES, Index.NOT_ANALYZED));   
  43.             writer.addDocument(doc);   
  44.         }   
  45.         writer.commit();   
  46.         writer.close();   
  47.         IndexReader reader = IndexReader.open(dir);   
  48.         Query query = IKQueryParser.parse(name, "衣服");   
  49.         Sort sort = new Sort(new SortField(field,SortField.DOUBLE,true)); //排序 false 升序 true降序   
  50.         IndexSearcher isearcher = new IndexSearcher(reader);   
  51.         isearcher.setSimilarity(new IKSimilarity());   
  52.         TopDocs topDocs =  isearcher.search(query, 5, sort);   
  53.         ScoreDoc scoreDocs[] = topDocs.scoreDocs;   
  54.         for (ScoreDoc scoreDoc : scoreDocs) {   
  55.             Document doc =  isearcher.doc(scoreDoc.doc);   
  56.             System.out.println(doc.get(field));   
  57.         }   
  58.         isearcher.close();   
  59.         dir.close();   
  60.     }   
  61. }  
import java.io.IOException;
import java.util.Locale;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.Field.Index;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.search.FieldComparator;
import org.apache.lucene.search.FieldComparatorSource;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.SortField;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.RAMDirectory;
import org.apache.lucene.util.Version;
import org.junit.Test;
import org.wltea.analyzer.lucene.IKAnalyzer;
import org.wltea.analyzer.lucene.IKQueryParser;
import org.wltea.analyzer.lucene.IKSimilarity;
public class LuceneSortTest {
	/**
	 * Lucene排序查询
	 */
	@Test
	public void testSort() throws Exception{
		String name = "name";
		String field = "price";
		String names[] = {"衣服","睡衣","漂亮衣服","好看衣服","男士衣服","女士衣服"};
		double price[] = {12.0,13.0,8.8,9.6,7.5,12.1};
		RAMDirectory dir = new RAMDirectory();
		Analyzer analyzer = new IKAnalyzer();
		IndexWriterConfig cfg = new IndexWriterConfig(Version.LUCENE_35, analyzer);
		IndexWriter writer = new IndexWriter(dir, cfg);
		for (int i=0;i<names.length;i++) {
			Document doc = new Document();
			doc.add(new Field(name, names[i], Store.YES, Index.ANALYZED));
			doc.add(new Field(field, String.valueOf(price[i]), Store.YES, Index.NOT_ANALYZED));
			writer.addDocument(doc);
		}
		writer.commit();
		writer.close();
		IndexReader reader = IndexReader.open(dir);
		Query query = IKQueryParser.parse(name, "衣服");
		Sort sort = new Sort(new SortField(field,SortField.DOUBLE,true)); //排序 false 升序 true降序
		IndexSearcher isearcher = new IndexSearcher(reader);
		isearcher.setSimilarity(new IKSimilarity());
		TopDocs topDocs =  isearcher.search(query, 5, sort);
		ScoreDoc scoreDocs[] = topDocs.scoreDocs;
		for (ScoreDoc scoreDoc : scoreDocs) {
			Document doc =  isearcher.doc(scoreDoc.doc);
			System.out.println(doc.get(field));
		}
		isearcher.close();
		dir.close();
	}
}

 

 

这段代码执行的结果为:

Java代码 复制代码  收藏代码
  1. 12.1  
  2. 12.0  
  3. 9.6  
  4. 8.8  
  5. 7.5  
12.1
12.0
9.6
8.8
7.5

 

 

在SortField里面有很多静态常量来提供给排序器作为排序的依据,Lucene里面自己定义好的排序实现已经基本能够满足我们的需求了,如果自己想定义一个自己的排序算法,那么可以继承FieldComparatorSource实现里面的方法:

 

Java代码 复制代码  收藏代码
  1. public FieldComparator newComparator(String fieldname, int numHits,   
  2.             int sortPos, boolean reversed) throws IOException {   
  3.         // TODO Auto-generated method stub   
  4.         return new DoubleFieldComparatorSource.DoubleFieldComparator();   
  5.     }  
public FieldComparator newComparator(String fieldname, int numHits,
			int sortPos, boolean reversed) throws IOException {
		// TODO Auto-generated method stub
		return new DoubleFieldComparatorSource.DoubleFieldComparator();
	}

 

里面的FieldComparator是一个抽象类,主要就是用来作比较使用的,定义自己的排序算法关键也在于继承这个抽象类,然后实现里面的方法,需要实现的方法如下:

 

Java代码 复制代码  收藏代码
  1. class DoubleFieldComparator extends FieldComparator{   
  2.         @Override  
  3.         public int compare(int slot1, int slot2) {   
  4.             return 0;   
  5.         }   
  6.         @Override  
  7.         public void setBottom(int slot) {   
  8.         }   
  9.         @Override  
  10.         public int compareBottom(int doc) throws IOException {   
  11.             return 0;   
  12.         }   
  13.         @Override  
  14.         public void copy(int slot, int doc) throws IOException {ub   
  15.         }   
  16.         @Override  
  17.         public void setNextReader(IndexReader reader, int docBase)   
  18.                 throws IOException {   
  19.         }   
  20.         @Override  
  21.         public Object value(int slot) {   
  22.             return null;   
  23.         }   
  24.     }  
class DoubleFieldComparator extends FieldComparator{
		@Override
		public int compare(int slot1, int slot2) {
			return 0;
		}
		@Override
		public void setBottom(int slot) {
		}
		@Override
		public int compareBottom(int doc) throws IOException {
			return 0;
		}
		@Override
		public void copy(int slot, int doc) throws IOException {ub
		}
		@Override
		public void setNextReader(IndexReader reader, int docBase)
				throws IOException {
		}
		@Override
		public Object value(int slot) {
			return null;
		}
	}

 

 

这里顺便列出Sort已经提供的比较值:

 

Java代码 复制代码  收藏代码
  1. SortField.SCORE 按积分排序   
  2. SortField.DOC 按文档排序   
  3. SortField.AUTO 域的值为intlongfloat都有效   
  4. SortField.STRING 域按STRING排序   
  5. SortField.FLOAT   
  6. SortField.LONG   
  7. SortField.DOUBLE   
  8. SortField.SHORT   
  9. SortField.CUSTOM 通过比较器排序   
  10. SortField.BYTE   
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值