Lucene学习笔记

Lucene基础知识

1 什么是全文检索

1.1 数据的分类

  1. 结构化数据

    格式固定、长度固定、数据类型固定。例如数据库中的数据。

  2. 非结构化数据

    word文档、pdf文档、邮件、html、txt格式不固定、长度不固定、数据类型不固定。

1.2 数据的查询

  1. 结构化数据的查询

    SQL语句,查询结构化数据的方法。简单、速度快。

  2. 非结构化数据的查询

    比如:从文本文件中找出包含spring单词的文件。

    1. 目测

    2. 使用程序把文档读到内存中,然后匹配字符串,顺序扫描。

    3. 把非结构化数据变成结构化数据

      先根据空格进行字符串拆分,得到一个单词列表,基于单词列表创建一个索引,然后查询索引,根据单词和文档的对应关系找到文档列表。这个过程叫全文索引。

      **索引:**一个为了提高查询速度,创建某种数据结构的集合。

1.3 全文检索

​ 先创建索引然后查询索引的过程叫全文索引。索引一次创建可以多次使用,表现为每次查询速度就很快了。

2 全文检索的应用场景

2.1 搜索引擎

​ 百度、360搜索、谷歌、搜狗

2.2 站内搜索

​ 论坛搜索、微博、文章搜索

2.3 电商搜索

​ 淘宝搜索、京东搜索

​ 只要有嗖嗖的地方就可以使用全文检索技术。

3 Lucene

​ Lucene是一个基于Java开发全文检索工具包。

3.1 Lucene实现全文检索的流程

  1. 创建索引
  • 获取文档

    原始文档:要基于哪些数据来进行搜索,那么这些数据就是原始文档。

    搜索引擎:使用爬虫获取原始文档。

    站内搜索:数据库中的数据

    案例:直接使用io流读取磁盘上的文件

  • 构建文档对象

    对应每个原始文档创建一个Document对象

    每个document对象中包含多个域(field)

    域中保存就是原始文档数据。

    ​ 域的名称

    ​ 域的值

    每个文档中都有唯一的编号,就是文档的id

  • 分析文档

    就是分词的过程

    1. 根据空格进行字符串拆分,得到一个单词列表
    2. 把单词统一转换成小写
    3. 去除标点符号
    4. 去除停用词(即无意义的词)

    每个关键词都封装成一个Term对象中。term对象中包含两部分内容:关键词所在的域、关键词本身,不同的域中拆分出来的相同的关键词是不同的term。

  • 创建索引

    基于关键词列表来创建一个索引,保存到索引库中。索引库中有索引和document对象和关键词与文档的对应关系,通过词语找文档,这种索引的结构叫倒排索引结构。

  1. 查询索引
  • 用户查询接口

    用户输入查询条件的地方,例如:百度的搜索框。

  • 把关键词封装成查询对象

    要查询的域,要搜索的关键词

  • 执行查询

    根据要查询的关键词到对应的域上进行搜索,找到关键词,根据关键词来找到对应文档。

  • 渲染结果

    根据文档id找到文档对象,进行高亮分页等处理。

4 入门案例

4.1 步骤分析

​ 首先熟悉一下Lucene的步骤:

  • 创建索引

    将用户要搜索的文档进行索引,索引存储在索引库(index)中。

    1. 获得原始文档:原始文档包括互联网上的网页、数据库中的数据、磁盘上的文件等。本案例中的原始内容就是磁盘上的文件:
      在这里插入图片描述

    2. 创建文档对象:获取原始内容的目的是为了索引,在索引前需要将原始内容创建成文档(Document),文档中包括一个一个的域(Field),域中存储内容(file_name文件名称、file_path文件路径、file_size文件大小、file_content文件内容)。

    在这里插入图片描述

    注意:每个Document可以有多个Field,不同的Document可以有不同的Field,同一个Document可以有相同的Field(域名和域值都相同),每个文档都有一个唯一的编号,即文档id。

    1. 分析文档:分析的过程是经过对原始文档提取单词、将字母转为小写、去除标点符号、去除停用词等过程生成最终的语汇单元,可以将语汇单元理解为一个一个的单词。每一个单词叫做一个Term,不同的域中拆分出来的相同的单词是不同的term。term的结构为——文档的域名+单词的内容。

    2. 创建索引:对所有文档分析得出的词汇单元进行索引,索引的目的就是为了搜索,最终实现只搜索被索引的词汇单元从而找到Document。

      在这里插入图片描述

      注意:创建索引是对词汇单元索引,通过词语找文档,这种索引的结构叫倒排索引结构

  • 查询索引

    查询索引也是搜索的过程。搜索就是用户输入关键字,从索引(index)中进行查找的过程。根据关键字搜索索引,根据索引找到对应的文档,从而找到要搜索的内容。

    1. 创建查询:用户输入查询关键字执行搜索之前需要先构建一个查询对象,查询对象中可以指定查询要搜索的Field文档域、查询关键字等,查询对象会生成具体的查询语法。例如:语法“fileName:lucene” 表示要搜索Field域的内容为“Lucene”的文档。
    2. 执行查询:搜索索引过程——根据查询语法在倒排索引词典表中分别找出对应搜索词的索引,从而找到索引所链接的文档链表。比如搜索语法为“fileName:lucene”表示搜索出fileName域中包含Lucene的文档。搜索过程就是在索引上查找域为fileName,并且关键字为Lucene的term,并根据term找到文档id列表。

4.2 代码编写

​ 首先需要从官方网站中下载lucene-7.4.0并解压。然后将以下jar包导入到工程中去:

在这里插入图片描述

需求:实现一个文件的搜索功能,通过关键字搜索文件,凡是文件名或文件内容包括关键字的文件都需要找出来。还可以根据中文词语进行查询,并且需要支持多个条件查询。

  • 创建索引

    @Test
    public void createIndex() throw Exception {
    	// 1. 创建indexWriter对象:需要两个参数directory索引库存放路径和indexWriterConfig对象
        Directory directory = FSDirectory.open(new File("D:\\ideaProjects\\index").toPath());
        IndexWriterConfig config = new IndexWriterConfig();
        IndexWriter indexWriter = new IndexWriter(directory, config);
        
        // 2. 获取原始文件
        // 路径
        File dir = new File("C:\Users\17163\Desktop\Java学习\searchsource");
        // 获取文件信息
        for (File f : dir.listFiles()) {
            // 文件名
            String fileName = f.getName();
            // 文件内容
            String fileContent = FileUtils.readFileToString(f);
            // 文件路径
            String filePath = f.getPath();
            // 文件大小
            long fileSize = FileUtils.sizeof(f);
            // 创建域
            // TextField参数:第一个:域的名称;第二个:域的内容;第三个:是否存储
            Field fileNameField = new TextField("fileName", fileName, Field.Store.YES);
            Field fieldPath = new TextField("path", filePath, Field.Store.YES);
            Field fieldContent = new TextField("content", fileContent, Field.Store.YES);
            Field fieldSize = new TextField("size", fileSize + "", Field.Store.YES);
            // 创建document对象
            Document document = new Document();
            document.add(fileNameField);
            document.add(fieldPath);
            document.add(fieldContent);
            document.add(fieldSize);
            // 创建索引,并写入索引库
            indexWriter.addDocument(document);
        }
        // 关闭indexWriter
        indexWriter.close();
    }
    

    执行上述代码后,index目录下会出现下面这些文件:可以用Luke工具进行查看索引文件

在这里插入图片描述

Luke工具:

在这里插入图片描述

  • 查询索引

    @Test
    public void searchIndex() throws Exception {
        // 1. 创建indexReader对象
        // 指定索引库存放的路径
        Directory directory = FSDirectory.open(new File("D:\\ideaProjects\\index").toPath());
        // 创建indexReader
        IndexReader inde
    }
    

    5 分析器

    ​ 默认使用的是标准分析器StandardAnalyzer

    5.1 分析器的效果

    ​ 使用Analyzer对象的tokenStream方法返回一个TokenStream对象。词对象包含了最终分词结果。

    实现步骤:

    1. 创建一个Analyzer对象,StandardAnalyzer对象
    2. 使用分词器对象的tokenStream方法获得一个TokenStream对象。
    3. 向TokenStream对象中设置一个引用,相当于数一个指针
    4. 调用TokenStream对象的rest方法,如果不调用会抛出异常
    5. 使用while循环遍历TokenStream方法
    6. 关闭TokenStream对象

    5.2 IKAnalyzer的使用方法

    1. 把IKAnalyzer的jar包添加到工程中

    2. 把配置文件和扩展词典添加到工程的classpath下

      注意:扩展词典严禁使用windows记事本编辑保存保证扩展词典的编码格式是utf-8。(记事本默认是utf-8+bom)

    扩展词典:添加一些新词

    停用词词典:无意义的词或者敏感词汇

    6 索引库维护

    6.1 添加文档

    6.2 删除文档

    • 删除全部
    • 根据查询、关键词删除文档

    6.3 修改文档

    7 索引库查询

    7.1 使用Query的子类

    1. TermQuery: 根据关键词进行查询,需要指定查询的域和查询的关键词
    2. RangeQuery:范围查询

    7.2 使用QueryParser进行查询

    ​ 可以对要查询的内容先分词,然后基于分词的结果进行查询。

    ​ 添加一个jar包:lucene-queryparser-7.4.0.jar

全部

  • 根据查询、关键词删除文档

6.3 修改文档

7 索引库查询

7.1 使用Query的子类

  1. TermQuery: 根据关键词进行查询,需要指定查询的域和查询的关键词
  2. RangeQuery:范围查询

7.2 使用QueryParser进行查询

​ 可以对要查询的内容先分词,然后基于分词的结果进行查询。

​ 添加一个jar包:lucene-queryparser-7.4.0.jar

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值