`
catastiger
  • 浏览: 138511 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

利用Boost影响Lucene查询结果的排序

阅读更多
前提:不对结果做sort操作.
   在搜索中,并不是所有的Document和Fields都是平等的.有些技术会要求到对其Doucment或者Fields的权值改变,默认值为:1.0F,以上需求都是通过改变Document的boost因子来改变的. 下面是通过lucene3.0,IKAnalyzer
1.通过设置doc boost改变排序结果
 
    /**
     * 设置DOC boost 值影响查询排序结果
     * @throws Exception
     */
    public void testBoost1() throws Exception{
        System.out.println("设置DOC boost 值影响查询排序结果");
        RAMDirectory ramDir = new RAMDirectory();
        Analyzer analyzer = new IKAnalyzer();
        IndexWriter iw = new IndexWriter(ramDir, analyzer, true ,IndexWriter.MaxFieldLength.LIMITED);
        
        String[] nameList = { "you are my friend", "a are my wife", "I love you" };
        String[] addList = { "b", "you are my wife", "c" };
        String[] fileList = { "1", "2", "3" };

        for (int i = 0; i < nameList.length; i++){
            Document doc = new Document();
            doc.add(new Field("name", nameList[i], Field.Store.YES, Field.Index.ANALYZED));
            doc.add(new Field("file", fileList[i], Field.Store.YES, Field.Index.ANALYZED));
            doc.add(new Field("address", addList[i], Field.Store.YES, Field.Index.ANALYZED));
            if (i == 2) {
                doc.setBoost(2.0f); 
            }
//            这里设置了第三个文档优先级最高,所以在搜索出来的结果中,该文档排在最前
            iw.addDocument(doc);
        }
        iw.close();

        IndexSearcher _searcher = new IndexSearcher(ramDir);
        String[] fields =new String[]{"name","address"};
        Query query=IKQueryParser.parseMultiField(fields, "you");

        TopDocs topDocs = _searcher.search(query,_searcher.maxDoc());
        ScoreDoc[] hits = topDocs.scoreDocs;
        for (int i = 0; i < hits.length; i++) {
            Document doc = _searcher.doc(hits[i].doc);
            System.out.println("name:"+doc.get("name"));
            System.out.println("file:"+doc.get("file"));
        }
        _searcher.close();
        
    }

  

if (i == 2) { doc.setBoost(2.0f); }这样I love you 将先输出,
2.通过设置query 影响排序
 /**
     * 设置query boost值影响排序结果,如果有排序sort,则完全按照sort结果进行
     * @throws Exception
     */
    public void testBoost2() throws Exception{
        System.out.println("设置query boost值影响排序结果");
        RAMDirectory ramDir = new RAMDirectory();
        Analyzer analyzer = new IKAnalyzer();
        IndexWriter iw = new IndexWriter(ramDir, analyzer, true ,IndexWriter.MaxFieldLength.LIMITED);
        
        String[] nameList = { "you are my friend", "a are my wife", "I love you" };
        String[] addList = { "b", "you are my wife", "c" };
        String[] fileList = { "1", "2", "3" };

        for (int i = 0; i < nameList.length; i++)
        {
            Document doc = new Document();
            doc.add(new Field("name", nameList[i], Field.Store.YES, Field.Index.ANALYZED));
            doc.add(new Field("file", fileList[i], Field.Store.YES, Field.Index.ANALYZED));
            doc.add(new Field("address", addList[i], Field.Store.YES, Field.Index.ANALYZED));
            iw.addDocument(doc);
        }
        iw.close();
        IndexSearcher _searcher = new IndexSearcher(ramDir);
        
        BooleanQuery bq = new BooleanQuery();
        QueryParser _parser = new QueryParser(Version.LUCENE_30,"name",analyzer);
        Query  _query = _parser.parse("you");
        _query.setBoost(2f);
        
        QueryParser _parser1 = new QueryParser(Version.LUCENE_30,"address",analyzer);
        Query  _query1 = _parser1.parse("you");
        _query1.setBoost(1f);
       
        bq.add(_query, BooleanClause.Occur.SHOULD);
        bq.add(_query1, BooleanClause.Occur.SHOULD);
//       
        
//          for(int i=0;i<2;i++){
//              QueryParser parser = new MultiFieldQueryParser(Version.LUCENE_30,new String[] {"name", "address" }, analyzer);
//              Query q1 = parser.parse("you");
//              bq.add(q1, BooleanClause.Occur.MUST);
//          }
//         
//         SortField[] sortFields = new SortField[1];  
//         SortField sortField = new SortField("file", SortField.INT, true);//false升序,true降序  
//         sortFields[0] = sortField;  
//         Sort sort = new Sort(sortFields);  
//         TopDocs topDocs = _searcher.search(bq,null,_searcher.maxDoc(),sort);
//        
        
        TopDocs topDocs = _searcher.search(bq,_searcher.maxDoc());
        ScoreDoc[] hits = topDocs.scoreDocs;
        for (int i = 0; i < hits.length; i++) {
            Document doc = _searcher.doc(hits[i].doc);
            System.out.println("name:"+doc.get("name"));
            System.out.println("file:"+doc.get("file"));
        }
        _searcher.close();
        
    }

结果如下:(name 的boost最高,所以name优先于address排序在前面)
设置query boost值影响排序结果
name:you are my friend
file:1
name:I love you
file:3
name:a are my wife
file:2

3.通过设置fields 的boost 影响排序
/**
     * 设置field boost 值影响查询排序结果,有排序则按照排序
     * @throws Exception
     */
     //没设置field boost 213 设置后是132
    public void testBoost3() throws Exception{
        System.out.println("设置fields boost 值影响查询排序结果");
        RAMDirectory ramDir = new RAMDirectory();
        Analyzer analyzer = new IKAnalyzer();
        IndexWriter iw = new IndexWriter(ramDir, analyzer, true ,IndexWriter.MaxFieldLength.LIMITED);
        String[] nameList = { "you are my friend", "a are my wife", "I love you" };
        String[] addList = { "b", "you are my wife", "c" };
        String[] fileList = { "1", "2", "3" };

        for (int i = 0; i < nameList.length; i++)
        {
            Document doc = new Document();
            Field nameField =  new Field("name", nameList[i], Field.Store.YES, Field.Index.ANALYZED);
            nameField.setBoost(20f);
            doc.add(nameField);
            doc.add(new Field("file", fileList[i], Field.Store.YES, Field.Index.ANALYZED));
            Field f = new Field("address", addList[i], Field.Store.YES, Field.Index.ANALYZED);
            f.setBoost(30f);
            doc.add(f);
            iw.addDocument(doc);
        }
        iw.close();
        
       
        IndexSearcher _searcher = new IndexSearcher(ramDir);
        String[] fields =new String[]{"name","file","address"};
        Query query=IKQueryParser.parseMultiField(fields, "you");
        
//        SortField[] sortFields = new SortField[1];  
//        SortField sortField = new SortField("file", SortField.INT, true);//false升序,true降序  
//        sortFields[0] = sortField;  
//        Sort sort = new Sort(sortFields);  
//        TopDocs topDocs = _searcher.search(query,null,_searcher.maxDoc(),sort);
        
        TopDocs topDocs = _searcher.search(query,_searcher.maxDoc());
        ScoreDoc[] hits = topDocs.scoreDocs;
        for (int i = 0; i < hits.length; i++) {
            Document doc = _searcher.doc(hits[i].doc);
            System.out.println("name:"+doc.get("name"));
            System.out.println("file:"+doc.get("file"));
        }
        _searcher.close();
        
    }

结果如下:(address 的boost最高,先排在前面了)
设置fields boost 值影响查询排序结果
name:a are my wife
file:2
name:you are my friend
file:1
name:I love you
file:3

分享到:
评论

相关推荐

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

    在Lucene4.x版本中,排序功能有了新的变化,本文将详细介绍如何利用Lucene实现文档的排序以及加分策略。 首先,Lucene的默认排序方式是基于文档得分,即通过TF-IDF(词频-逆文档频率)算法来评估文档与查询的相关度...

    一步一步跟我学习Lucene源码之lucene的各种Field

    Lucene的核心功能包括文档的索引、查询解析、排序以及结果的评分。 Field是Lucene中非常关键的概念,它是构成文档的基本单元。一个文档可以包含多个Field,每个Field都有特定的名称和值,用于表示文档的不同部分。...

    Lucene4.X实战类baidu搜索的大型文档海量搜索系统-15.Lucene高级进阶1 共23页.pptx

    8. **自定义得分**:Lucene允许用户为Document设置boost因子,从而影响文档的搜索得分,提升某些文档的优先级。 9. **分词器的使用**:课程详细讲解了Lucene中分词器的概念,包括不同分词器的使用和配置,这对于...

    lucene学习全方面剖析总结

    4. **结果排序**:根据文档与查询的相关性对搜索结果进行排序,最终展示给用户。 #### Lucene 的基础概念 - **正向信息**:指文档本身的元数据,如文档ID、创建时间等。 - **反向信息**:即倒排索引,记录了哪些...

    lucene-2.2.0-src

    3. 结果排序:通过评分函数(如TF-IDF)计算每个匹配文档的相关性,按照得分排序返回结果。 4. 拓展查询:Lucene支持多字段搜索、近似搜索、模糊搜索等高级查询特性。 五、性能优化 1. 压缩存储:Lucene使用压缩...

    Lucene5学习之评分Scoring

    在Lucene 5版本中,对于搜索结果的排序和评分机制进行了优化,使得搜索体验更加精准。本文将深入探讨Lucene5中的评分(Scoring)机制,帮助读者理解如何通过源码分析和工具使用来提升搜索质量。 首先,我们需要了解...

    lucene in Action

    书中会介绍如何编写查询表达式,理解查询树的构造和执行过程,并且学习如何使用Boost函数对不同字段或查询项进行加权,以实现更精准的搜索结果排序。此外,还会讨论相关性评分算法,如TF-IDF,以及如何自定义评分...

    Solr评分整理汇总.docx

    如果你希望通过干预 Lucene 查询来改变查询结果的排序,你就需要对 Lucene 的得分计算有所理解。 Lucene 的得分计算公式考虑了多个因素,包括文档权重、域权重、调整因子、逆文档频率等。文档权重是指在索引时给...

    lucene相关技术

    3. **排序与展示**:根据Score对搜索结果进行排序,通常高分的文档优先展示。 4. **更新与删除**:如果文档有更新或需要删除,可以通过IndexWriter来完成。 **三、Lucene高级特性** 1. **多字段搜索**:用户可以...

    Elasticsearch核心知识篇、项目中如何使用、如何优化进阶

    - **概念理解**:在Elasticsearch中,可以使用Boost机制为特定字段或查询增加权重,从而影响最终的搜索结果排序。这对于需要对某些关键词进行特殊强调的应用场景非常有用。 - **实现方式**:通过在查询语句中加入`...

Global site tag (gtag.js) - Google Analytics