lucene的自我学习小结,大牛路过请过指教

1.什么是全文检索

全文检索:就是对海量非结构数据进行建立索引,在对建立的索引进行查询的过程。

例如:图书馆找书,商品的快速查找等等

全文检索的应用场景?

一般用在搜索引擎,和一些站内搜索中海量数据的优化查询速度的应用。

为什么要学习全文检索

为了解决海量数据查询慢的问题,

数据一般分为结构性数据,非结构性数据

结构性数据是:长度固定,数据类型固定,结构固定,例如我们学习的mysql,oracle数据库表数据

非结构性数据:一般是,长度不固定,类型不固定,大小不固定。例如我们的一些文档,比如.txt .pdf .java 等等的文档。

2.如何给海量数据创建索引,实现快速查找的流程

其中主要有三种

  1. 通过持久层框架对数据库数据的查询

  2. 通过IO流建读取文档给文档建创建索引,根据索引实现快速的查找

  3. 对海量的数据进行文件对象的创建,创建索引对象,读取源文件的数据,将源文件的对象进行遍历,获取每一个源文件的信息,创建文档对象将每一个源文件信息存放进文档对象中,然后通过索引对象调用存储文档对象的方法,将存储文档信息的文档对象存入索引库,

其中重点的是将具有统一查询条件信息,对应的文档的路径按照key对应多个value 的方式进行存储,例如:D://aaa.bbb.ccc.ddd.text,D://aaa.bbb.ccc.eee.txt。同时为了查询的效率横向搜索更简洁,可以将key值进行切割,分成多个key对应一个value,例如将搜索条件‘’JAVA编程思想”进行切割,JAVA,编程,思想,三个key对应一个VALUE。

3.给源文件数据建立索引库的基本步骤

  1. 创建directory文件对象,指定索引库保存的位置

  2. 创建indexwriter对象(又称为索对象),获取文件数据的名称,大小,路径,内容。

  3. 读取源文件的信息,将获取的所有源文件进行遍历

  4. 获取每一个源文件的信息

  5. 创建文档对象,将每一个源文件的信息存入文档中

  6. 索引对象调用添加文档对象对应的方法,将存有文档信息的文档对象存入索引库中

  7. 关闭indexWriter对象

     //创建一个director对象
          //保存在磁盘中
          //Directory directory =new RAMDirectory();
          Directory directory=   FSDirectory.open(new File("D:\\temp\\index").toPath());
          //创建indexWriter索引对象
          IndexWriterConfig config = new IndexWriterConfig(new IKAnalyzer());
          IndexWriter indexWriter = new IndexWriter(directory,config);
          //读取源文件的数据
          File file = new File("D:\\品优购\\lucene2018\\02.参考资料\\searchsource");
          File[] files = file.listFiles();
          for (File file1 : files) {
              String file1Name = file1.getName();
              String file1Path = file1.getPath();
              String fileContent = FileUtils.readFileToString(file1, "UTF-8");
              long fileSize = FileUtils.sizeOf(file1);
              //获取索引库的文件信息
              TextField fileName = new TextField("name",file1Name, Field.Store.YES);
              TextField filePath = new TextField("path",file1Path, Field.Store.YES);
              TextField fileContent1 = new TextField("content",fileContent, Field.Store.YES);
              TextField fileSize1 = new TextField("size",fileSize+"", Field.Store.YES);
              //创建Document文档对象
              Document document = new Document();
              //将读取的源文件数据存入document文档对象中
              document.add(fileName);
              document.add(filePath);
              document.add(fileContent1);
              document.add(fileSize1);
              //将document对象存入索引数据库中
              indexWriter.addDocument(document);
          }
          //关闭流对象
          indexWriter.close();

4.代码实现查询索引库的流程分析

  1. 创建一个director对象,指定索引库的位置

  2. 创建一个indexreader对象

  3. 创建一个index Searcher对象,构造方法中的参数index Reader对象

  4. 创建一个Queary对象,TermQueary(创建根据关键词查询的对象)

  5. 执行查询,得到一个TopDocs对象-->(得到查询的结果,其中有两个部分,一个是查询结果的总记录数,一个是文档的列表信息)

  6. 取查询结果的总记录数

  7. 取文档列表

  8. 打印文档列表

  9. 关闭index Reader对象

     //创建director对象
          Directory directory=   FSDirectory.open(new File("D:\\temp\\index").toPath());
          //创建读取director对象的IndexReader对象
          IndexReader indexReader = DirectoryReader.open(directory);
          //创建一个indexSearch对象,构造方法传入参数是IndexReader对象
          IndexSearcher indexSearcher = new IndexSearcher(indexReader);
          //创建一个Queary对象,TreamQueary
          TermQuery termQuery = new TermQuery(new Term("content", "java"));
          //执行查询,得到一个TopDocs对象
          TopDocs docs = indexSearcher.search(termQuery, 10);
          //取查询结果的总记录数
          System.out.println("查询总记录数:"+docs.totalHits);
          //取文档列表
          ScoreDoc[] scoreDocs = docs.scoreDocs;
          for (ScoreDoc scoreDoc : scoreDocs) {
              int id = scoreDoc.doc;
              //获取文档对象
              Document document = indexSearcher.doc(id);
              //打印文档列表
              System.out.println(document.get("name"));
              System.out.println(document.get("path"));
              // System.out.println(document.get("content"));
              System.out.println(document.get("size"));
              System.out.println("-----------------------");

          }
          //关闭IndexReader流
          indexReader.close();

5.查看分析器的分析效果及实现步骤

最初的分词器: 庖丁解牛分词器, 近几年才出的: IKanlays分词器

默认使用的分析器是:standarAnalyzer

使用Analyzer对象的tokenStream方法返回一个tokenStream对象,该对象中包含了最终分词的效果。

实现步骤:

  1. 创建一个Analyzer(分析器)对象,StandardAnalyzer对象-->默认的标准分词器(此处我们可以使用创建IK分词器的对象--new IKAnalyzer(),这样分词出来的信息会更实际化一些)

  2. 使用分析器对象的tokenStream的方法获得一个TokenStream对象

  3. 向TokenStream对象设置一个引用,相当于设置一个指针,获取指针就可以获取指针对应的值。

  4. 调用TokenStream对象的rest方法,如果不调用就会抛异常,必须调用,作用是将随机的指针设置到第一的位置

  5. 使用while 循环百遍历TokenStream对象

  6. 关闭TokenStream对象


      1. 创建一个Analyzer(分析器)对象,StandardAnalyzer对象-->标准分词器
          // StandardAnalyzer analyzer = new StandardAnalyzer();
          IKAnalyzer analyzer = new IKAnalyzer();
    //       2. 使用分析器对象的tokenStream的方法获得一个TokenStream对象
          TokenStream tokenStream = analyzer.tokenStream("", "老师,我王旭要坐你腿上玩评优购");
    //       3. 向TokenStream对象设置一个引用,相当于设置一个指针,获取指针就可以获取指针对应的值。
          CharTermAttribute charTermAttribute = tokenStream.addAttribute(CharTermAttribute.class);
    //       4. 调用TokenStream对象的rest方法,如果不调用就会抛异常,必须调用,作用是将随机的指针设置到第一的位置
          tokenStream.reset();
    //       5. 使用while 循环百遍历TokenStream对象
          while(tokenStream.incrementToken()){
              System.out.println(charTermAttribute.toString());
          }
    //       6. 关闭TokenStream对象
          tokenStream.close()

6.对索引库信息进行CRUD操作

此时在类中的重复代码比较冗余,可以使用前置注解@Before抽取重复代码块,简化代码书写。


  @Before
  public void init() throws IOException {
    indexWriter = new IndexWriter(FSDirectory.open(new File("D:\\temp\\index").toPath()), new IndexWriterConfig(new IKAnalyzer()));
  }

对索引库添加文档信息的实现步骤

  1. 创建director文件对象,并指定所应库的位置

  2. 创建IndexWriter对象

  3. 创建文档对象

  4. 向文档对象中存入域信息

  5. 将文档信息写入索引库(indexWriter对象通过addDocument()方法将文档信息存储进索引库中)

  6. 释放indexWriter对象

    对索引库信息进行删除的基本思路步骤

    1. 创建director对象,并指定索引库的位置

    2. 创建indexWriter对象

    3. 使用indexWriter对象调用deleteAll方法。

    4. 释放indexWriter对象

多索引库信息的更新操作基本实现步骤

  1. 创建indexWriter对象,指定索引库的位置

  2. 创建文档Document对象

  3. 向文档中添加域信息

  4. 使用indexWriter独享调用update方法(传入需要被修改的文件的关键词信息:new Term());

  5. 释放indexWriter对象

未完待续,其中还有两种查询方法,晚点再补上。

猜你喜欢

转载自www.cnblogs.com/lv-tian/p/10631816.html