Lucene学习笔记一

Lucene简介

  • Lucene是apache软件基金会4 jakarta项目组的一个子项目,是一个开放源代码的全文检索引擎工具包,但它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎(英文与德文两种西方语言)。Lucene的目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能,或者是以此为基础建立起完整的全文检索引擎。Lucene是一套用于全文检索和搜寻的开源程式库,由Apache软件基金会支持和提供。Lucene提供了一个简单却强大的应用程式接口,能够做全文索引和搜寻。在Java开发环境里Lucene是一个成熟的免费开源工具。就其本身而言,Lucene是当前以及最近几年最受欢迎的免费Java信息检索程序库。人们经常提到信息检索程序库,虽然与搜索引擎有关,但不应该将信息检索程序库与搜索引擎相混淆。
  • lucene是一个基于java开发全文检索工具包。

全文检索

  • 先创建索引然后查询索引的过程叫做全文检索

1.创建索引

1.1 获得原始文档
  • 是指要索引和搜索的内容。原始内容包括互联网上的网页、数据库中的数据、磁盘上的文件等。
1.2 构建文档对象
  • 对应每一个原始对象创建一个Document对象
  • 每个document对象中包含多个域(field)
  • 域中保存的是原始文档数据。一个文档可以有多个域
    1.域的名称
    2.域的值
    加粗样式
1.3 分析文档
  • 分析的过程是经过对原始文档提取单词、将字母转为小写、去除标点符号、去除停用词等过程生成最终的语汇单元,可以将语汇单元理解为一个一个的单词。
  • 每个关键词封装在一个Term对象中
    Term:
    1.关键词
    2.关键词在的域
1.4 创建索引
  • 对所有文档分析得出的语汇单元进行索引,索引的目的是为了搜索,最终要实现只搜索被索引的语汇单元从而找到Document(文档)。
    在这里插入图片描述倒排索引
  • 创建索引是对语汇单元索引,通过词语找文档,这种索引的结构叫倒排索引结构。
  • 传统方法:根据文件找到该文件的内容,在文件内容中匹配搜索关键字,这种方法是顺序扫描方法,数据量大、搜索慢。

2.查询索引

  • 查询接口
  • 封装查询对象
  • 执行查询
  • 渲染结果(展示给用户看)

3.入门案例

  • 环境搭建
    lucene-analyzers-common-7.4.0.jar
    lucene-core-7.4.0.jar
    commons-io.jar
    步骤:
  1. 创建一个director对象,指定索引库保存的位置。
  2. 基于directory对象创建一个IndexWriter对象。
  3. 读取磁盘上的文件,对应每一个文件创建一个文档对象。
  4. 向文档对象中添加域
  5. 把文档对象写入索引库
  6. 关闭indexwriter对象
    代码如下
 /**
     * 创建索引
     * @throws IOException
     */
    @Test
    public void saveIndex()  throws IOException {
//        1. 创建一个directory对象,指定索引库保存的位置。
        Directory directory = FSDirectory.open(new File("D:\\y study\\index").toPath());
//        2. 基于directory对象创建一个IndexWriter对象。
        IndexWriter indexWriter = new IndexWriter(directory, new IndexWriterConfig());

//        3. 读取磁盘上的文件,对应每一个文件创建一个文档对象。
        File dir = new File("D:\\1全套黑马\\黑马57最新的笔记\\61.会员版(2.0)-就业课(2.0)-Lucene\\61.会员版(2.0)-就业课(2.0)-Lucene\\lucene\\02.参考资料\\searchsource");
        File[] files = dir.listFiles();
        for (File file : files) {
            //取文件名
            String fileName = file.getName();
            //文件的路径
            String filePath = file.getPath();
            //文件的内容
            String fileContent = FileUtils.readFileToString(file, "utf-8");
            //文件的大小
            long fileSize = FileUtils.sizeOf(file);
            //创建Field
            //参数1:域的名称 参数2:域的内容 参数3:是否存储
            Field fieldName = new TextField("name", 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 = new Document();
            //4.向文档对象中添加域
            document.add(fieldName);
            document.add(fieldPath);
            document.add(fieldContent);
            document.add(fieldSize);
            //5. 把文档对象写入索引库
            indexWriter.addDocument(document);
        }
//        6. 关闭indexwriter对象
        indexWriter.close();
    }

  • .使用luke查看索引库中的内容
  • 查询索引库
    步骤:
  1. 创建一个director对象,指定索引库的位置。
  2. 创建一个IndexReader对象。
  3. 创建一个IndexSearcher对象,构造方法中的参数indexReader对象。
  4. 创建一个Query对象,TermQuery。
  5. 执行查询,得到一个TopDocs对象。
  6. 取查询结果的总记录数。
  7. 取文档列表
  8. 打印文档中的内容。
  9. 关闭indexwriter对象
    代码如下:
 /**
     * 查询索引
     * @throws IOException
     */
    @Test
    public void serachIndex() throws IOException {
        // 1. 创建一个director对象,指定索引库的位置。
        Directory directory = FSDirectory.open(new File("D:\\y study\\index").toPath());
        // 2. 创建一个IndexReder对象。
        IndexReader indexReader = DirectoryReader.open(directory);
        // 3. 创建一个IndexSearcher对象,构造方法中的参数indexReader对象。
        IndexSearcher indexSearcher = new IndexSearcher(indexReader);
        // 4. 创建一个Query对象,TermQuery。
        Query query = new TermQuery(new Term("content","spring"));
        // 5. 执行查询,得到一个TopDocs对象。
        //参数一:查询对象   参数二:查询结果返回的最大记录数
        TopDocs topDocs = indexSearcher.search(query, 10);
        // 6. 取查询结果的总记录数。
        System.out.println("查询总记录数:"+ topDocs.totalHits);
        // 7. 取文档列表
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;
        // 8. 打印文档中的内容。
        for (ScoreDoc doc : scoreDocs) {
            int docId = doc.doc;
            Document document = indexSearcher.doc(docId);
            System.out.println(document.get("name"));
            System.out.println(document.get("path"));
            System.out.println(document.get("size"));
//          System.out.println(document.get("content"));
            System.out.println("-------------------------------------------------------------分割线");
        }
        // 9. 关闭indexwriter对象
        indexReader.close();
    }

运行结果:
在这里插入图片描述

4.分析器

  • 默认使用的分析器是StandardAnalyzer
    查看分析器的分析效果
    实现步骤:
    1 创建一个Analyzer对象,StandardAnalyzer对象
    2 使用分析器对象的tokenStream方法获得一个TokenStream对象
    3 向TokenStream对象中设置一个引用,相当一个指针
    4 调用TokenStream对象的reset方法
    5 使用while循环遍历TOkenStream对象
    6 关闭TokenStream对象
    代码如下:
 @Test
    public void testTokenStream() throws  Exception {
        //1 创建一个Analyzer对象,StandardAnalyzer对象
        Analyzer analyzer = new StandardAnalyzer();
        //2 使用分析器对象的tokenStream方法获得一个TokenStream对象
        TokenStream tokenStream = analyzer.tokenStream("", "The Spring Framework provides a");
        //3 向TokenStream对象中设置一个引用,相当一个指针
        CharTermAttribute charTermAttribute = tokenStream.addAttribute(CharTermAttribute.class);
        //4 调用TokenStream对象的reset方法
        tokenStream.reset();
        //5 使用while循环遍历TOkenStream对象
        while (tokenStream.incrementToken()) {
            System.out.println(charTermAttribute.toString());
        }
        //6 关闭TokenStream对象
        tokenStream.close();
    }

结果显示:
在这里插入图片描述

但是如果是对中文进行分析是什么效果呢?
如果对 " 全文检索是将整本书java、整篇文章中的任意内容信息查找出来的检索" 进行分析
结果如下:
在这里插入图片描述我们会发现只分析了一个字,显然处理中文不合理。

IKAnalyze的使用

  • 添加jar包到工程中
  • 把配置文件和扩展词典添加到工程的classpath下

在这里插入图片描述在这里插入图片描述代码如下:

  @Test
    public void testTokenStream() throws Exception {
        //1 创建一个Analyzer对象,StandardAnalyzer对象
        //Analyzer analyzer = new StandardAnalyzer();
        Analyzer analyzer = new IKAnalyzer();
        //2 使用分析器对象的tokenStream方法获得一个TokenStream对象
        TokenStream tokenStream = analyzer.tokenStream("", "全文检索是将整本书java、整篇文章中的任意内容信息查找出来的检索");
        //3 向TokenStream对象中设置一个引用,相当一个指针
        CharTermAttribute charTermAttribute = tokenStream.addAttribute(CharTermAttribute.class);
        //4 调用TokenStream对象的reset方法
        tokenStream.reset();
        //5 使用while循环遍历TOkenStream对象
        while (tokenStream.incrementToken()) {
            System.out.println(charTermAttribute.toString());
        }
        //6 关闭TokenStream对象
        tokenStream.close();
    }

运行结果:
在这里插入图片描述根据结果可以知道,使用IKAnalyze后分析的中文是一个个的词语,达到了我们想要的结果。

  1. 如果我们想要是某两个字被分析为词语,可以加入扩展词典。
  2. 如果希望停用该词,则加入停用词典。
    如何用IK分析器?
    action: 在创建索引时添加分析器IK
    代码如下:
    @Test
    public void saveIndex() throws IOException {
//        1. 创建一个directory对象,指定索引库保存的位置。
        Directory directory = FSDirectory.open(new File("D:\\y study\\index").toPath());
//        2. 基于directory对象创建一个IndexWriter对象。
     //   IndexWriter indexWriter = new IndexWriter(directory, new IndexWriterConfig());
        IndexWriterConfig config = new IndexWriterConfig(new IKAnalyzer());
        IndexWriter indexWriter = new IndexWriter(directory,config);

//        3. 读取磁盘上的文件,对应每一个文件创建一个文档对象。
        File dir = new File("D:\\1全套黑马\\黑马57最新的笔记\\61.会员版(2.0)-就业课(2.0)-Lucene\\61.会员版(2.0)-就业课(2.0)-Lucene\\lucene\\02.参考资料\\searchsource");
        File[] files = dir.listFiles();
        for (File file : files) {
            //取文件名
            String fileName = file.getName();
            //文件的路径
            String filePath = file.getPath();
            //文件的内容
            String fileContent = FileUtils.readFileToString(file, "utf-8");
            //文件的大小
            long fileSize = FileUtils.sizeOf(file);
            //创建Field
            //参数1:域的名称 参数2:域的内容 参数3:是否存储
            Field fieldName = new TextField("name", 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 = new Document();
            //4.向文档对象中添加域
            document.add(fieldName);
            document.add(fieldPath);
            document.add(fieldContent);
            document.add(fieldSize);
            //5. 把文档对象写入索引库
            indexWriter.addDocument(document);
        }
//        6. 关闭indexwriter对象
        indexWriter.close();
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值