Lucene相关度排序学习笔记

1、什么是相关度排序

Lucene对查询关键字和索引文档的相关度进行打分,得分高的就排在前边。
1.1 如何打分

Lucene是在用户进行检索时实时根据搜索的关键字计算出来的,分两步:
1、计算出词(term)的权重。
2、根据词的权重值,计算文档相关度得分。
明确索引的最小单位是一个Term(索引词典的一个词),搜索也是从term中搜素,再根据term找到文档,term对文档的重要性成为权重,影响term权重有两个因素:

  • Term Frequency (tf): 指此Term在此文档中出现了多少次。tf 越大说明越重要。词(Term)在文档中出现的次数越多,说明此(Term)对该文档越重要,如“Lucene”这个词,在文档中出现的次数很多,说明该文档主要就是讲Lucene技术的。
  • Document Frequency (df): 指有多少文档包含次Term。df 越大说明越不重要。比如,在一篇英语文档中,this出现的次数更多,就说明越重要吗?不是的,有越多的文档包含此词(Term),说明此词(Term)太普通,不足以区分这些文档,因而重要性越低。

1.2 怎样影响相关度排序
boost是一个加权值(默认加权值为1.0f),它可以影响权重的计算。

  • 在索引时对某个文档中的field设置加权值高,在搜索时匹配到这个文档就可能排在前边。
  • 在搜索时对某个域进行加权,在进行组合域查询时,匹配到加权值高的域最后计算的相关度得分就 高。

设置boost是给域(field)或者Document设置的。
1.3 人为影响相关度排序
查询的时候通过设置域的权重,从而影响查询结果


    /**
     * 测试相关度排序
     * @throws Exception
     */
    @Test
    public void testIndexSearch2() throws Exception {

        //1. 创建分词器(对搜索的关键词进行分词使用)
        //注意: 分词器要和创建索引的时候使用的分词器一模一样
        Analyzer analyzer = new IKAnalyzer();

        //需求: 不管是名称域还是品牌域或者是分类域有关于手机关键字的查询出来
        //查询的多个域名
        String[] fields = {"name", "categoryName", "brandName"};

        //设置影响排序的权重, 这里设置域的权重
        Map<String, Float> boots = new HashMap<>();
        boots.put("categoryName", 10000000000f);

        //从多个域查询对象
        MultiFieldQueryParser multiFieldQueryParser = new MultiFieldQueryParser(fields, analyzer, boots);
        //设置查询的关键词
        Query query = multiFieldQueryParser.parse("手机");

        //4. 创建Directory目录对象, 指定索引库的位置
        Directory dir = FSDirectory.open(Paths.get("E:\\dir"));
        //5. 创建输入流对象
        IndexReader indexReader = DirectoryReader.open(dir);
        //6. 创建搜索对象
        IndexSearcher indexSearcher = new IndexSearcher(indexReader);
        //7. 搜索, 并返回结果
        //第二个参数: 是返回多少条数据用于展示, 分页使用
        TopDocs topDocs = indexSearcher.search(query, 10);

        //获取查询到的结果集的总数, 打印
        System.out.println("=======count=======" + topDocs.totalHits);

        //8. 获取结果集
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;

        //9. 遍历结果集
        if (scoreDocs != null) {
            for (ScoreDoc scoreDoc : scoreDocs) {
                //获取查询到的文档唯一标识, 文档id, 这个id是lucene在创建文档的时候自动分配的
                int  docID = scoreDoc.doc;
                //通过文档id, 读取文档
                Document doc = indexSearcher.doc(docID);
                System.out.println("==================================================");
                //通过域名, 从文档中获取域值
                System.out.println("===id==" + doc.get("id"));
                System.out.println("===name==" + doc.get("name"));
                System.out.println("===price==" + doc.get("price"));
                System.out.println("===image==" + doc.get("image"));
                System.out.println("===brandName==" + doc.get("brandName"));
                System.out.println("===categoryName==" + doc.get("categoryName"));

            }
        }
        //10. 关闭流
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值