lucene的自我学习小结,大牛路过请过指教
1.什么是全文检索?
全文检索:就是对海量非结构数据进行建立索引,在对建立的索引进行查询的过程。
例如:图书馆找书,商品的快速查找等等
全文检索的应用场景?
一般用在搜索引擎,和一些站内搜索中海量数据的优化查询速度的应用。
为什么要学习全文检索?
为了解决海量数据查询慢的问题,
数据一般分为结构性数据,非结构性数据
结构性数据是:长度固定,数据类型固定,结构固定,例如我们学习的mysql,oracle数据库表数据
非结构性数据:一般是,长度不固定,类型不固定,大小不固定。例如我们的一些文档,比如.txt .pdf .java 等等的文档。
2.如何给海量数据创建索引,实现快速查找的流程?
其中主要有三种
- 通过持久层框架对数据库数据的查询
- 通过IO流建读取文档给文档建创建索引,根据索引实现快速的查找
- 对海量的数据进行文件对象的创建,创建索引对象,读取源文件的数据,将源文件的对象进行遍历,获取每一个源文件的信息,创建文档对象将每一个源文件信息存放进文档对象中,然后通过索引对象调用存储文档对象的方法,将存储文档信息的文档对象存入索引库,
其中重点的是将具有统一查询条件信息,对应的文档的路径按照key对应多个value 的方式进行存储,例如:D://aaa.bbb.ccc.ddd.text,D://aaa.bbb.ccc.eee.txt。同时为了查询的效率横向搜索更简洁,可以将key值进行切割,分成多个key对应一个value,例如将搜索条件‘’JAVA编程思想”进行切割,JAVA,编程,思想,三个key对应一个VALUE。
3.给源文件数据建立索引库的基本步骤
- 创建directory文件对象,指定索引库保存的位置
- 创建indexwriter对象(又称为索对象),获取文件数据的名称,大小,路径,内容。
- 读取源文件的信息,将获取的所有源文件进行遍历
- 获取每一个源文件的信息
- 创建文档对象,将每一个源文件的信息存入文档中
- 索引对象调用添加文档对象对应的方法,将存有文档信息的文档对象存入索引库中
- 关闭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.代码实现查询索引库的流程分析
- 创建一个director对象,指定索引库的位置
- 创建一个indexreader对象
- 创建一个index Searcher对象,构造方法中的参数index Reader对象
- 创建一个Queary对象,TermQueary(创建根据关键词查询的对象)
- 执行查询,得到一个TopDocs对象-->(得到查询的结果,其中有两个部分,一个是查询结果的总记录数,一个是文档的列表信息)
- 取查询结果的总记录数
- 取文档列表
- 打印文档列表
- 关闭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对象,该对象中包含了最终分词的效果。
实现步骤:
- 创建一个Analyzer(分析器)对象,StandardAnalyzer对象-->默认的标准分词器(此处我们可以使用创建IK分词器的对象--new IKAnalyzer(),这样分词出来的信息会更实际化一些)
- 使用分析器对象的tokenStream的方法获得一个TokenStream对象
- 向TokenStream对象设置一个引用,相当于设置一个指针,获取指针就可以获取指针对应的值。
- 调用TokenStream对象的rest方法,如果不调用就会抛异常,必须调用,作用是将随机的指针设置到第一的位置
- 使用while 循环百遍历TokenStream对象
- 关闭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()));
}
对索引库添加文档信息的实现步骤
- 创建director文件对象,并指定所应库的位置
- 创建IndexWriter对象
- 创建文档对象
- 向文档对象中存入域信息
- 将文档信息写入索引库(indexWriter对象通过addDocument()方法将文档信息存储进索引库中)
-
释放indexWriter对象
对索引库信息进行删除的基本思路步骤
- 创建director对象,并指定索引库的位置
- 创建indexWriter对象
- 使用indexWriter对象调用deleteAll方法。
- 释放indexWriter对象
多索引库信息的更新操作基本实现步骤
- 创建indexWriter对象,指定索引库的位置
- 创建文档Document对象
- 向文档中添加域信息
- 使用indexWriter独享调用update方法(传入需要被修改的文件的关键词信息:new Term());
- 释放indexWriter对象
未完待续,其中还有两种查询方法,晚点再补上。