`
landows
  • 浏览: 18342 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

关于lucene自定义排序 FieldComparatorSource

阅读更多
其实关于FieldComparatorSource的lucene默认实现,应该已经满足我们对结果排序的需求了,比如:

如果我们希望对搜索结果按照一定的业务规则,人工干预排序,不妨尝试一下继承一下FieldComparatorSource以及实现FieldComparator类。
     以下是一个用户期望根据用户登录Ip对应的城市的相应数据排在最前面。
创建索引:
    /**
	 * 创建place索引
	 */
	public static void createPlaceIndex(){
		Analyzer  analyzer = new IKAnalyzer();
		PerFieldAnalyzerWrapper  perFieldAnalyzerWrapper = new PerFieldAnalyzerWrapper(analyzer);
		try {
			
			//perFieldAnalyzerWrapper.addAnalyzer("price", new WhitespaceAnalyzer());
			IndexWriter writer = new IndexWriter(FSDirectory.open(new File(index_path5)), perFieldAnalyzerWrapper, true,IndexWriter.MaxFieldLength.LIMITED);
			Document doc  = new Document();
			
			doc.add(new Field("placeName", "杭州西湖 测试开发", Field.Store.YES, Field.Index.ANALYZED));
			doc.add(new Field("placeName2", "杭州西湖 测试开发", Field.Store.YES, Field.Index.NOT_ANALYZED));
			writer.addDocument(doc);
			doc  = new Document();
			doc.add(new Field("placeName", "西湖 九天", Field.Store.YES, Field.Index.ANALYZED));
			doc.add(new Field("placeName2", "西湖 九天", Field.Store.YES, Field.Index.NOT_ANALYZED));
			writer.addDocument(doc);
			doc  = new Document();
			doc.add(new Field("placeName", "扬州廋西湖 高级开发", Field.Store.YES, Field.Index.ANALYZED));
			doc.add(new Field("placeName2", "扬州廋西湖 高级开发", Field.Store.YES, Field.Index.NOT_ANALYZED));
			writer.addDocument(doc);
			doc  = new Document();
			doc.add(new Field("placeName", "苏州西湖", Field.Store.YES, Field.Index.ANALYZED));
			doc.add(new Field("placeName2", "苏州西湖", Field.Store.YES, Field.Index.NOT_ANALYZED));
			writer.addDocument(doc);
			
		
			
			writer.close();
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

实现Comparator以及ComparatorSource
     class PlaceNameSortComparatorSource  extends FieldComparatorSource {
	private String userLocation ;
	public PlaceNameSortComparatorSource(String userLocation ){
		this.userLocation = userLocation;
	}
	@Override
	public FieldComparator newComparator(String fieldname, int numHits,
			int sortPos, boolean reversed) throws IOException {
		// TODO Auto-generated method stub
		return new PlaceComparator(numHits,fieldname,userLocation);
	}
	
}


 final class PlaceComparator extends FieldComparator {
    private final String[] values;
    private String[] currentReaderValues;
    private final String field;
    private String bottom;
    private String userLocation;
    

    PlaceComparator(int numHits, String field, String userLocation) {
      values = new String[numHits];
      this.field = field;
      this.userLocation = userLocation;
    }

    @Override
    public int compare(int slot1, int slot2) {
    	
      int cmpValue=0;
      final String v1 = values[slot1];
      final String v2 = values[slot2];

      if(v1.indexOf(userLocation) !=-1){
    	  cmpValue= -999999999;
      }
      if(v2.indexOf(userLocation) !=-1){
    	  cmpValue= -999999999;
      }else{
    	  cmpValue = 999999999;
      }
      
      System.out.println(slot1+"-"+slot2);
      System.out.println(v1+"-"+v2);
      System.out.println("cmpValue="+cmpValue);
      return cmpValue;
    }

    @Override
    public int compareBottom(int doc) {
      final String v2 = currentReaderValues[doc];
      if(v2.indexOf(userLocation) !=-1){
    	  return -999999999;
      }
      if(bottom.indexOf(userLocation)!=-1){
    	  return -999999999;
      }
      return bottom.compareTo(v2);
    }

    @Override
    public void copy(int slot, int doc) {
      values[slot] = currentReaderValues[doc];
    }

    @Override
    public void setNextReader(IndexReader reader, int docBase) throws IOException {
      currentReaderValues = FieldCache.DEFAULT.getStrings(reader, field);
    }
    
    @Override
    public void setBottom(final int bottom) {
      this.bottom = values[bottom];
    }

    @Override
    public Comparable value(int slot) {
      return values[slot];
    }
    
  }


搜索测试:
    		Query trquery  = new PrefixQuery(new Term("placeName","西湖" ));   
		BooleanQuery booleanQuery = new BooleanQuery();
		TermQuery  tq  = new TermQuery(new Term("placeName","西湖"));

		IndexReader  indexReader = IndexReader.open(FSDirectory.open(new File(index_path5)));
		SortField sortField = new SortField("placeName2", new PlaceNameSortComparatorSource("扬州"),true );
		Sort sort = new Sort();     
		sort.setSort(sortField);
		
		Searcher  searcher = new IndexSearcher(indexReader);
		
		TopDocs topDocs = searcher.search(tq,null,100,sort);
		
		for (ScoreDoc hits:topDocs.scoreDocs){
			Document doc = searcher.doc(hits.doc);
			System.out.println("doc = "+doc.get("placeName"));
		}


运行结果:
doc = 扬州廋西湖 高级开发
doc = 西湖 九天
doc = 苏州西湖
doc = 杭州西湖 测试开发
  • 大小: 49.5 KB
分享到:
评论

相关推荐

    lucene自定义排序实现

    因此,了解如何在 Lucene 中实现自定义排序是非常关键的。在这个话题中,我们将深入探讨如何根据特定的业务需求对搜索结果进行定制排序。 首先,我们要明白 Lucene 默认的排序机制。默认情况下,Lucene 搜索结果是...

    Lucene5学习之自定义排序

    此外,Lucene5引入了`FieldComparatorSource`和`FieldDoc`接口,允许开发者自定义比较器和文档的排序行为。这些高级特性可以用来实现更复杂的排序逻辑,比如基于动态计算的分数或者处理多值字段的排序。 在实际操作...

    java Lucene 中自定义排序的实现

    Lucene中的自定义排序功能和Java集合中的自定义排序的实现方法差不多,都要实现一下比较接口. 在Java中只要实现Comparable接口就可以了.但是在Lucene中要实现SortComparatorSource接口和ScoreDocComparator接口.在...

    lucene 自定义评分

    这样,Lucene 就会使用我们的自定义评分规则进行匹配和排序。 在实际应用中,可能还需要考虑其他因素,如用户偏好、文档质量、关键词位置等。这些都可以通过自定义相似度类中的方法来实现。例如,对于位置敏感的...

    lucene排序.zip

    《深入理解Lucene排序机制:从关键词频率到自定义优先级》 在信息检索领域,Lucene是一个广泛使用的全文搜索引擎库。它提供了强大的文本分析、索引和搜索功能,而排序作为搜索结果的重要组成部分,是Lucene的一个...

    lucene的排序过滤和分页.zip

    本资料主要探讨了Lucene中的排序、过滤和分页技术,这些都是构建高效、实用的信息检索系统的重要组成部分。 **排序(Sorting)** 排序是Lucene中的一项核心功能,允许我们根据文档的某个或多个字段来对搜索结果...

    深入了解Lucene之三 排序算法.doc

    深入了解 Lucene 之三排序算法 ...Lucene 的排序算法是基于 tf-idf 模型的,通过 tf、idf、coord、queryNorm、norm 等评分因子来计算文档的分数,并提供了丰富的 API 使用户可以实现自定义的排序算法。

    lucene排序、设置权重、优化、分布式搜索.pdf

    Lucene 排序、设置权重、优化、分布式搜索 Lucene 是一个高性能的搜索引擎库,它提供了强大的文本搜索和索引能力。下面我们将详细介绍 Lucene 的排序、设置权重、优化和分布式搜索等知识点。 一、Lucene 排序 ...

    lucene4.3 按坐标距离排序

    5. **Sorting**:在Lucene中,我们可以自定义排序规则,包括基于地理位置的距离排序。这可以通过实现`SortComparatorSource`接口来自定义比较器,或者使用`FieldComparatorSource`来创建一个基于特定字段(如地理...

    Lucene5学习之排序-Sort

    “Lucene5学习之排序-Sort”这个标题表明了我们要探讨的是关于Apache Lucene 5版本中的排序功能。Lucene是一个高性能、全文检索库,它提供了强大的文本搜索能力。在这个主题中,我们将深入理解如何在Lucene 5中对...

    Lucene5学习之Filter过滤器

    1. 创建自定义Filter子类,实现必要的过滤逻辑。 2. 使用Filter的getDocIdSet()方法生成一个BitSet,该BitSet标记了哪些文档满足过滤条件。 3. 将Filter与Query一起传递给Searcher的search()方法,Lucene会自动使用...

    Lucene5学习之自定义Collector

    这篇博客“Lucene5学习之自定义Collector”显然聚焦于如何在Lucene 5版本中通过自定义Collector来优化搜索结果的收集过程。Collector是Lucene搜索框架中的一个重要组件,它负责在搜索过程中收集匹配的文档,并根据...

    SSH + Lucene + 分页 + 排序 + 高亮 模拟简单新闻网站搜索引擎--data

    - Lucene支持多种排序策略,如按照评分评分(Score排序),按照文档ID排序,或者根据自定义字段排序。 - 在查询时,通过设置Sort对象指定排序依据和顺序。 5. 高亮显示: - Lucene提供Highlighter类来高亮搜索结果...

    Lucene5学习之自定义同义词分词器简单示例

    本篇将聚焦于"Lucene5学习之自定义同义词分词器简单示例",通过这个主题,我们将深入探讨如何在Lucene5中自定义分词器,特别是实现同义词扩展,以提升搜索质量和用户体验。 首先,理解分词器(Analyzer)在Lucene中...

    SSH + Lucene + 分页 + 排序 + 高亮 模拟简单新闻网站搜索引擎--news.part2

    SSH + Lucene + 分页 + 排序 + 高亮 模拟简单新闻网站搜索引擎--NewsWithSearch.part3 SSH + Lucene + 分页 + 排序 + 高亮 模拟简单新闻网站搜索引擎--NewsWithSearch.part2 SSH + Lucene + 分页 + 排序 + 高亮 ...

    SSH + Lucene + 分页 + 排序 + 高亮 模拟简单新闻网站搜索引擎--dic

    SSH + Lucene + 分页 + 排序 + 高亮 模拟简单新闻网站搜索引擎--NewsWithSearch.part3 SSH + Lucene + 分页 + 排序 + 高亮 模拟简单新闻网站搜索引擎--NewsWithSearch.part2 SSH + Lucene + 分页 + 排序 + 高亮 ...

    Lucene4.X实战类baidu搜索的大型文档海量搜索系统-18.Lucene排序 共6页.pptx

    《Lucene4.X实战:构建类百度搜索的大型...通过合理运用得分计算、加分策略和自定义排序,我们可以为用户提供更加符合他们需求的搜索体验。在实际应用中,还需要不断调整和优化,以应对各种复杂场景和大量数据的挑战。

Global site tag (gtag.js) - Google Analytics