lucene学习笔记一:lucene是什么实现步骤以及索引的创建查询修改删除

Posted java开发架构师

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了lucene学习笔记一:lucene是什么实现步骤以及索引的创建查询修改删除相关的知识,希望对你有一定的参考价值。

1. lucene学习笔记一

1.1. lucene的作用

  1. 实现文本搜索的框架,用于文本的搜索,非结构化文件的搜索。可以搜索文件里面的内容。用于电商网站上的搜索。

  2. 实现文本搜索首先要进行索引的创建,索引创建了才能实现文本搜索。

lucene执行流程

1.2. lucene的实现步骤

  1. 获取原始文档

  • 通过爬虫爬取,并存储下来。

  1. 创建文档对象

  • 每个文档有多个域,包含:文件名,路径,内容,大小。

  • 每个文档都有一个编号。

  1. 分析文档

  • 将大写转为小写,去除标点,停用词等最终生成语汇单元。每个语汇单元里的单词叫做一个term

  • 不同域中即使term一样也不是同一个term.

  • 必须是在同一个域中,并且一样才是一个term.

term区别
  1. 创建索引

  • 索引库包含两个方面:一个是索引内容,一个是文件对象。

  • 通过对获取的原始文档进行分析,然后分析出term,并创建文档的对象域。

  • 将分析出的term存入索引库,将文档的对象存入索引库。

  • 创建索引,

  • 搜索时,执行查询,获取文档结果。

创建索引

1.3. lucene案例学习

  1. 创建java工程

  2. 导入包

  • lucene核心包

  • lucene分析词包

  • lucene查询包

  • io流包

  • junit测试包

  1. 创建索引

  • 虽然步骤第一步不是创建索引,但是我们应该倒着推,因为,创建索引和索引库相连,自然最应该先想到

  • 包含两个参数,一个是创建的索引保存路径,一个是需要索引参数,

  • indexWriter是一个索引写入流,需要关闭

1IndexWriter indexWriter=new IndexWriter(directory, indexWriterConfig);
  1. 创建索引保存路径

  • 如果没有该路径会自动创建。

1Directory directory =FSDirectory.open(new File("d:\\luceneindex\\index"));
  1. 配置索引写入流的参数

  • 包含一个版本,一个文字分析器

  • 实例化一个分析器。注意是抽象类需要子类实例化。

1Analyzer analyzer=new StandardAnalyzer();
2IndexWriterConfig indexWriterConfig=new IndexWriterConfig(Version.LATEST, analyzer);
  1. 创建一个Document文件,这个文件用来专门存储各种域对象

1Document document=new Document();
  1. 通过文件流的输入获取要分析的资源,并将资源存储到数组中

1File file=new File("D:\\luceneindex\\searchsource");
2File[] listFiles = file.listFiles();
  1. for增强循环遍历该数组

  • 获取文件的名字,路径,大小,内容,并存储到各个域中。

  • 注意,不同的内容存储不同的域,存储的域要表明,名字,要存储的对象,是否存储到索引中

 1for(File file2:listFiles) {
2    //文件名称
3    String file_name=file2.getName();    
4    Field fileNameField=new TextField("fileName",file_name,Store.YES);
5    //文件大小
6    long file_size = FileUtils.sizeOf(file2);
7    Field fileSizeField=new LongField("fileSize", file_size, Store.YES);
8    //文件路径
9    String file_path = file2.getPath();
10    Field filePathField=new StoredField("filePath", file_path);
11    //文件内容
12    String file_context = FileUtils.readFileToString(file2);
13    Field fileContextField=new TextField("fileContext", file_context,Store.YES);
  1. 将所有域对象存储到document文档中

  • 主要是为了统一管理

1document.add(fileContextField);
2document.add(filePathField);
3document.add(fileSizeField);
4document.add(fileNameField);
  1. 使用indexWriter对象将document中的内容添加到索引库中,并将索引也添加到了索引库

1//使用indexWriter对象将document对象写入索引库,此时进行索引创建,并将索引和document对象写入索引库。
2indexWriter.addDocument(document);
  1. 关闭indexWriter流

    • 完成索引的创建。

1//关流
2indexWriter.close();

1.4. 查询索引

  1. 创建一个Directory对象,获取索引所在路径

1//第一步:创建一个Directory对象,获取索引库存放的位置。
2Directory directory=FSDirectory.open(new File("d:\\luceneindex\\index"));
  1. 创建索引读取流

1//第二步;创建一个indexReader索引读取流,指定Directory路径
2IndexReader indexReader=DirectoryReader.open(directory);
  1. 创建索引查找对象并指定查找的内容,即:读取的内容

1//第三步:indexSearcher对象,需要指定IndexReader对象
2IndexSearcher indexSearcher=new IndexSearcher(indexReader);
  1. 创建一个TermQuery对象指定查询的关键词

1//第四步:创建一个TermQuery对象,指定查询的域和关键词
2Query query=new TermQuery(new Term("fileName","apache"));
  1. 执行查询

  • 并返回n条记录

1//第五步:执行查询
2TopDocs topDocs = indexSearcher.search(query, 2);
  1. 返回查询结果

1//第六步:返回查询结果,遍历查询结果并输出
2ScoreDoc[] scoreDocs = topDocs.scoreDocs;
  1. 遍历查询结果

  • 通过结果中的id值,将查询的内容返回到文件对象中

  • 通过文件对象获取文件中的内容。

 1for(ScoreDoc scoreDoc:scoreDocs) {
2    int doc = scoreDoc.doc;
3    Document document=indexSearcher.doc(doc);
4    //文件名
5    String fileName=document.get("fileName");
6    System.out.println(fileName);
7    String fileContext=document.get("fileContext");
8    System.out.println(fileContext);
9    String fileSize=document.get("fileSize");
10    System.out.println(fileSize);
11    String filePath=document.get("filePath");
12    System.out.println(filePath);
13}
  1. 关闭流

1//第七步:关闭indexReader流
2indexReader.close();
  1. 搜索使用的分析器和索引使用的分析器要一致。

1.5. 索引的删除

  1. 创建一个IndexWriter对象,注意这个对象是包含索引存储路径,和所使用分析器的对象。

1public IndexWriter getIndexWriter() throws Exception{
2    Directory directory = FSDirectory.open(new File("D:\\temp\\index"));
3    // Directory directory = new RAMDirectory();//保存索引到内存中 (内存索引库)
4    Analyzer analyzer = new StandardAnalyzer();// 官方推荐
5    IndexWriterConfig config = new IndexWriterConfig(Version.LATEST, analyzer);
6    return new IndexWriter(directory, config);
7}
  1. 删除文档

1//全删除
2@Test
3public void testAllDelete() throws Exception {
4    IndexWriter indexWriter = getIndexWriter();
5    indexWriter.deleteAll();
6    indexWriter.close();
7}
  1. 条件删除

1//根据条件删除
2@Test
3public void testDelete() throws Exception {
4    IndexWriter indexWriter = getIndexWriter();
5    Query query = new TermQuery(new Term("fileName","apache"));
6    indexWriter.deleteDocuments(query);
7    indexWriter.close();
8}

1.6. 修改索引

  1. 使用updateDocument方法

  • 修改的是域对象

 1//修改
2@Test
3public void testUpdate() throws Exception {
4    IndexWriter indexWriter = getIndexWriter();
5    Document doc = new Document();
6    doc.add(new TextField("fileN""测试文件名",Store.YES));
7    doc.add(new TextField("fileC""测试文件内容",Store.YES));
8    indexWriter.updateDocument(new Term("fileName","lucene"), doc, new IKAnalyzer());
9    indexWriter.close();
10}

1.7. 查询索引

  1. 查询所有:使用MatchAllDocsQuery类

  • printResult是一个方法。打印的方法。

 1//查询所有
2@Test
3public void testMatchAllDocsQuery() throws Exception {
4    IndexSearcher indexSearcher = getIndexSearcher();
5    Query query = new MatchAllDocsQuery();
6    System.out.println(query);
7    printResult(indexSearcher, query);
8    //关闭资源
9    indexSearcher.getIndexReader().close();
10}
  1. 精确查询:TermQuery

  2. 根据数值范围查询

 1//根据数值范围查询
2@Test
3public void testNumericRangeQuery() throws Exception {
4    IndexSearcher indexSearcher = getIndexSearcher();
5    //false是不包含左边区间,true是包含右边区间
6    Query query = NumericRangeQuery.newLongRange("fileSize"47L200Lfalsetrue);
7    System.out.println(query);
8    printResult(indexSearcher, query);
9    //关闭资源
10    indexSearcher.getIndexReader().close();
11}
  1. 组合查询

  • BooleanQuery

 1//可以组合查询条件
2@Test
3public void testBooleanQuery() throws Exception {
4    IndexSearcher indexSearcher = getIndexSearcher();
5    BooleanQuery booleanQuery = new BooleanQuery();
6    Query query1 = new TermQuery(new Term("fileName","apache"));
7    Query query2 = new TermQuery(new Term("fileName","lucene"));
8    //  select * from user where id =1 or name = 'safdsa'
9    booleanQuery.add(query1, Occur.MUST);//必须,该名字上必须有apache
10    booleanQuery.add(query2, Occur.SHOULD);//非必须,可以没有
11    System.out.println(booleanQuery);
12    printResult(indexSearcher, booleanQuery);
13    //关闭资源
14    indexSearcher.getIndexReader().close();
15}

1.8. 使用解析查询

  1. 利用QueryParser查询

 1//条件解释的对象查询
2@Test
3public void testQueryParser() throws Exception {
4    IndexSearcher indexSearcher = getIndexSearcher();
5    //参数1: 默认查询的域  
6    //参数2:采用的分析器
7    QueryParser queryParser = new QueryParser("fileName",new IKAnalyzer());
8    // *:*   域:值
9    Query query = queryParser.parse("fileName:lucene is apache OR fileContent:lucene is apache");
10
11    printResult(indexSearcher, query);
12    //关闭资源
13    indexSearcher.getIndexReader().close();
14}
  1. 多个默认查询域

  • 使用MultiFieldQueryParser

 1//条件解析的对象查询   多个默念域
2@Test
3public void testMultiFieldQueryParser() throws Exception {
4    IndexSearcher indexSearcher = getIndexSearcher();
5    String[] fields = {"fileName","fileContent"};
6    //参数1: 默认查询的域  
7    //参数2:采用的分析器
8    MultiFieldQueryParser queryParser = new MultiFieldQueryParser(fields,new IKAnalyzer());
9    // *:*   域:值
10    Query query = queryParser.parse("lucene is apache");
11    printResult(indexSearcher, query);
12    //关闭资源
13    indexSearcher.getIndexReader().close();
14}


以上是关于lucene学习笔记一:lucene是什么实现步骤以及索引的创建查询修改删除的主要内容,如果未能解决你的问题,请参考以下文章

lucene学习笔记

Lucene学习笔记

Lucene学习笔记-------Lucene基础

[lucene系列笔记1]lucene6的安装与配置(Windows系统)

lucene学习笔记

Lucene(7.3.1)学习笔记-Document类源码解析