程序员社区

Lucene 查询索引库

Hello,欢迎来到程序员社区。 今天聊一聊 Lucene 查询索引库,希望对大家有所帮助。

Java面试手册PDF下载:https://www.hicxy.com/219-2

以后用的分词库为IKAnalyzer中文分词库。
Lucene 查询索引库插图

查询

Lucene 查询索引库插图1

Lucene 查询索引库插图2

说明:这是QueryParser的继承结构,在这里我们用的是MultiFieldQueryParser.这个类的好处可以选择多个属性进行查询。而QueryParser只能选择一个。
Lucene 查询索引库插图3

分页

先创建出数据:
Lucene 查询索引库插图4

Lucene 查询索引库插图5

读取数据看看是否创建成功:
Lucene 查询索引库插图6

Lucene 查询索引库插图7
说明:
1) 在全文检索系统中,一般查询出来的内容比较多,所以必须将查询出来的内容进行分页处理。
2) 原理同hibernate的分页查询。在hibernate的分页查询中,有两个参数:
int firstResult 当前页的第一行在数据库里的行数
int maxResult 每页显示的页数

搜索方式

使用查询字符串

QueryParser->Query对象
可以使用查询条件
“lucene AND 互联网” 都出现符合查询条件
“lucene OR 互联网” 只要出现其一就符合查询条件
Lucene 查询索引库插图8

Lucene 查询索引库插图9

自己创建与配置Query对象

关键词查询(TermQuery)

Lucene 查询索引库插图10

Lucene 查询索引库插图11
注:因为保存引索的时候是通过分词器保存,所以所有的因为在索引
库里都为小写,所以lucene必须得小写,不然查询不到。如果使用
查询字符串进行查询,对应的语法格式为:title:lucene

查询所有文档

Lucene 查询索引库插图12

如果使用查询字符串,对应语法:*:*

范围查询

Lucene 查询索引库插图13
如果使用查询字符串,
第一个: id:[5 TO 15]
第二个: id:{5 TO 15}
注:在lucene中,处理数字是不能直接写入的,要进行转化。NumberStringTools帮助类给出了转化工具:
Lucene 查询索引库插图14

在工具类DocumentUtils中也做相应的转化:
Lucene 查询索引库插图15

Lucene 查询索引库插图16

通配符查询

Lucene 查询索引库插图17

如果使用查询字符串:tit编程电子书汇总le:lucen?

短语查询

Lucene 查询索引库插图18

上面的0代表第0个位置
上面的1代表第3个位置
使用查询字符串:title:”lucene ? ? 互联网”

Boolean查询

可以把多个查询条件组合成一个查询条件
Lucene 查询索引库插图19

如图为:同时满足title中有lucene关键字和ID为5到15的所有索引数据。不包括5和15
使用查询字符串:+id:{5 TO 15} +title:lucene
注意:
1、 单独使用MUST_NOT 没有意义
2、 MUST_NOT和MUST_NOT 无意义,检索无结果
3、单独使用SHOULD:结果相当于MUST
4、SHOULD和MUST_NOT: 此时SHOULD相当于MUST,结果同MUST和MUST_NOT
5、MUST和SHOULD:此时SHOULD无意义,结果为MUST子句的检索结果

过滤

Lucene 查询索引库插图20
利用indexSearch.search的重载函数的过滤器参数实现对结果的过滤。从这里可以看出这是一个范围过滤器。第二个参数与第三个参数为5,15。但是luce编程电子书汇总ne会把这两个参数当作字符串来对待。所以这样搜索结果为0。
进行如下处理:
Lucene 查询索引库插图21
Lucene 查询索引库插图22

凡是数字类型的都必须经过这样的方式进行处理。

Lucene 查询索引库插图23

凡是日期类型的都必须经过这样的方式进行处理。这样才能保证结果的正确性。

排序

相关度得分

实验一:
在索引库中内容完全相同的情况下,用几个关键词搜索,看是否得分相同。
结果:
同一个关键词得分对于所有的Document是一样的。但是不同的关键词的分数不一样。关键词和文本内容匹配越多,得分越高。也就是相关度得分就高
实验二:
再插入一个Document,在其中的content中增加一个关键词,然后保存到索引库中。如图:
Lucene 查询索引库插图24

在content中,google的后面又加了一个词”互联网”。然后再进行搜索,这个时候,id为26的被排到了第一位。相关度得分最高。因为其他的Document在content中匹配”互联网”只有一处,而id为26的有两处。
结果:
同一个关键词如果在所有匹配的文本中的相关度得分不一样,按照相关度得分从高到低的顺序排列。
实验三:
如果想从百度上排名第一,就得控制相关度得分。在lucene中,可以人为控制相关度得分。如图:
Lucene 查询索引库插图25
利用Document.setBoost可以控制得分。默认值为1
结论:
利用Document.setBoost可以人为控制相关度得分,从而把某一个引索内容排到最前面。
Lucene 查询索引库插图26

按照某个字段进行排序

Lucene 查询索引库插图27
如图所示的代码,重载了indexSearcher.search方法。在这个方法中,Sort对 象就是指定的按照id升序排列。SortField.INT指定了ID的类型。类型不一样,大小的比较就不一样。
Lucene 查询索引库插图28

上面代码查询出来以后是按照id的升序排列。
Lucene 查询索引库插图29
这个代码为按照id的降序排列。其中最后一个参数为reverse
Reverse为false 升序(默认)
Reverse 为true 降序
注:按照某个字段进行排序与相关度得分没有关系。

高亮

高亮的作用

1) 使关键字的颜色和其他字的颜色不一样,这样关键字就比较突出。
方法:在关键字周围加上前缀和后缀

    font color=’red’>中国font>

2) 生成摘要(从关键词出现最多的地方截取一段文本),可以配置要截取文本的字符数量。

编程步骤

/**
 * 高亮
 *    * 使关键字变色
 *       *  设置
 *       *  使用
 *    * 控制摘要的大小
 * @author AdminiJava面试手册strator
 */
public class HighlighterTest {
    @Test
    Java面试手册public void testSearchIndex() throws Exception{
        IndexSearcher indexSearcher = new IndexSearcher(LuceneUtils.directory);
        QueryParser queryParser = new MultiFieldQueryParser(Version.LUCENE_30, new String[]{"title","content"}, LuceneUtils.analyzer);
        Query query = queryParser.parse("Lucene");
        TopDocs topDocs = indexSearcher.search(query, 25);
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;
        /***********************************************************************/
            /**
             * 给关键字加上前缀和后缀
             */
            Formatter formatter = new SimpleHTMLFormatter("","");
            /**
             * scorer封装了关键字
             */
            Scorer scorer = new QueryScorer(query);
            Highlighter highlighter = new Highlighter(formatter,scorer);
            /**
             * 创建一个摘要
             */
            Fragmenter fragmenter = new SimpleFragmenter(10);
            highlighter.setTextFragmenter(fragmenter);
        /***********************************************************************/
        List articleList = new ArrayList();
        for(ScoreDoc scoreDoc:scoreDocs){
            float score = scoreDoc.score;
            System.out.println(score);//相关的得分
            Document document =  indexSearcher.doc(scoreDoc.doc);
            Article article = DocumentUtils.document2Article(document);
            /*
             * 使用高亮器
             */
            /**
             * 1、分词器
             *      查找关键词
             * 2、字段
             *      在哪个字段上进行高亮
             * 3、字段的内容
             *      把字段的内容提取出来
             */
            String titleText = highlighter.getBestFragment(LuceneUtils.analyzer, "title", document.get("title"));
            String contentText = highlighter.getBestFragment(LuceneUtils.analyzer, "content", document.get("content"));
            if(titleText!=null){
                article.setTitle(titleText);
            }
            if(contentText!=null){
                article.setContent(contentText);
            }
            articleList.add(article);
        }

        for(Article article:articleList){
            System.out.println(article.getId());
            System.out.println(article.getTitle());
            System.out.println(article.getContent());
        }
    }
}

创建和配置高量器

Lucene 查询索引库插图30

编程电子书汇总

Lucene 查询索引库插图31

一个高亮器的创建需要两个条件:
Formatter 要把关键词显示成什么样子
Scorer 查询条件
Fragmenter设置文本的长度。默认为100。
如果文本的内容长度超过所设定的大小,超过的部分将显示不出来。

使用高亮器

Lucene 查询索引库插图32

Lucene 查询索引库插图33

getBestFragment为得到高亮后的文本。
参数:

  1. 分词器

    如果是英文:StandardAnalyzer
    如果是中文:IKAnalyzer
    
  2. 在哪个属性上进行高亮

  3. 要高亮的内容

时间不一定能证明很多东西,但是一定能看透很多东西。坚信自己的选择,不动摇,使劲跑,明天会更好。

赞(0) 打赏
未经允许不得转载:IDEA激活码 » Lucene 查询索引库

一个分享Java & Python知识的社区