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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_33322074/article/details/89929836

1. lucene学习笔记一

1.1. lucene的作用

  1. 实现文本搜索的框架,用于文本的搜索,非结构化文件的搜索。可以搜索文件里面的内容。用于电商网站上的搜索。
  2. 实现文本搜索首先要进行索引的创建,索引创建了才能实现文本搜索。

lucene执行流程

1.2. lucene的实现步骤

  1. 获取原始文档
    • 通过爬虫爬取,并存储下来。
  2. 创建文档对象
    • 每个文档有多个域,包含:文件名,路径,内容,大小。
    • 每个文档都有一个编号。
  3. 分析文档
    • 将大写转为小写,去除标点,停用词等最终生成语汇单元。每个语汇单元里的单词叫做一个term
    • 不同域中即使term一样也不是同一个term.
    • 必须是在同一个域中,并且一样才是一个term.

term区别

  1. 创建索引
    • 索引库包含两个方面:一个是索引内容,一个是文件对象。
    • 通过对获取的原始文档进行分析,然后分析出term,并创建文档的对象域。
    • 将分析出的term存入索引库,将文档的对象存入索引库。
    • 创建索引,
    • 搜索时,执行查询,获取文档结果。

创建索引

1.3. lucene案例学习

  1. 创建java工程
  2. 导入包
    • lucene核心包
    • lucene分析词包
    • lucene查询包
    • io流包
    • junit测试包
  3. 创建索引
    • 虽然步骤第一步不是创建索引,但是我们应该倒着推,因为,创建索引和索引库相连,自然最应该先想到
    • 包含两个参数,一个是创建的索引保存路径,一个是需要索引参数,
    • indexWriter是一个索引写入流,需要关闭
IndexWriter indexWriter=new IndexWriter(directory, indexWriterConfig);
  1. 创建索引保存路径
    • 如果没有该路径会自动创建。
Directory directory =FSDirectory.open(new File("d:\\luceneindex\\index"));
  1. 配置索引写入流的参数
    • 包含一个版本,一个文字分析器
    • 实例化一个分析器。注意是抽象类需要子类实例化。
Analyzer analyzer=new StandardAnalyzer();
IndexWriterConfig indexWriterConfig=new IndexWriterConfig(Version.LATEST, analyzer);
  1. 创建一个Document文件,这个文件用来专门存储各种域对象
Document document=new Document();
  1. 通过文件流的输入获取要分析的资源,并将资源存储到数组中
File file=new File("D:\\luceneindex\\searchsource");
File[] listFiles = file.listFiles();
  1. for增强循环遍历该数组
    • 获取文件的名字,路径,大小,内容,并存储到各个域中。
    • 注意,不同的内容存储不同的域,存储的域要表明,名字,要存储的对象,是否存储到索引中
for(File file2:listFiles) {
    //文件名称
    String file_name=file2.getName();	
    Field fileNameField=new TextField("fileName",file_name,Store.YES);
    //文件大小
    long file_size = FileUtils.sizeOf(file2);
    Field fileSizeField=new LongField("fileSize", file_size, Store.YES);
    //文件路径
    String file_path = file2.getPath();
    Field filePathField=new StoredField("filePath", file_path);
    //文件内容
    String file_context = FileUtils.readFileToString(file2);
    Field fileContextField=new TextField("fileContext", file_context,Store.YES);
  1. 将所有域对象存储到document文档中
    • 主要是为了统一管理
document.add(fileContextField);
document.add(filePathField);
document.add(fileSizeField);
document.add(fileNameField);
  1. 使用indexWriter对象将document中的内容添加到索引库中,并将索引也添加到了索引库
//使用indexWriter对象将document对象写入索引库,此时进行索引创建,并将索引和document对象写入索引库。
indexWriter.addDocument(document);
  1. 关闭indexWriter流
    • 完成索引的创建。
//关流
indexWriter.close();

1.4. 查询索引

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

  1. 创建索引读取流
//第二步;创建一个indexReader索引读取流,指定Directory路径
IndexReader indexReader=DirectoryReader.open(directory);

  1. 创建索引查找对象并指定查找的内容,即:读取的内容
//第三步:indexSearcher对象,需要指定IndexReader对象
IndexSearcher indexSearcher=new IndexSearcher(indexReader);

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

  1. 执行查询
    • 并返回n条记录
//第五步:执行查询
TopDocs topDocs = indexSearcher.search(query, 2);

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

  1. 遍历查询结果
    • 通过结果中的id值,将查询的内容返回到文件对象中
    • 通过文件对象获取文件中的内容。
for(ScoreDoc scoreDoc:scoreDocs) {
    int doc = scoreDoc.doc;
    Document document=indexSearcher.doc(doc);
    //文件名
    String fileName=document.get("fileName");
    System.out.println(fileName);
    String fileContext=document.get("fileContext");
    System.out.println(fileContext);
    String fileSize=document.get("fileSize");
    System.out.println(fileSize);
    String filePath=document.get("filePath");
    System.out.println(filePath);
}

  1. 关闭流
//第七步:关闭indexReader流
indexReader.close();

  1. 搜索使用的分析器和索引使用的分析器要一致。

1.5. 索引的删除

  1. 创建一个IndexWriter对象,注意这个对象是包含索引存储路径,和所使用分析器的对象。
public IndexWriter getIndexWriter() throws Exception{
    Directory directory = FSDirectory.open(new File("D:\\temp\\index"));
    // Directory directory = new RAMDirectory();//保存索引到内存中 (内存索引库)
    Analyzer analyzer = new StandardAnalyzer();// 官方推荐
    IndexWriterConfig config = new IndexWriterConfig(Version.LATEST, analyzer);
    return new IndexWriter(directory, config);
}

  1. 删除文档
//全删除
@Test
public void testAllDelete() throws Exception {
    IndexWriter indexWriter = getIndexWriter();
    indexWriter.deleteAll();
    indexWriter.close();
}

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

1.6. 修改索引

  1. 使用updateDocument方法
    • 修改的是域对象
//修改
@Test
public void testUpdate() throws Exception {
    IndexWriter indexWriter = getIndexWriter();
    Document doc = new Document();
    doc.add(new TextField("fileN", "测试文件名",Store.YES));
    doc.add(new TextField("fileC", "测试文件内容",Store.YES));
    indexWriter.updateDocument(new Term("fileName","lucene"), doc, new IKAnalyzer());
    indexWriter.close();
}

1.7. 查询索引

  1. 查询所有:使用MatchAllDocsQuery类
    • printResult是一个方法。打印的方法。
//查询所有
@Test
public void testMatchAllDocsQuery() throws Exception {
    IndexSearcher indexSearcher = getIndexSearcher();
    Query query = new MatchAllDocsQuery();
    System.out.println(query);
    printResult(indexSearcher, query);
    //关闭资源
    indexSearcher.getIndexReader().close();
}

  1. 精确查询:TermQuery
  2. 根据数值范围查询
//根据数值范围查询
@Test
public void testNumericRangeQuery() throws Exception {
    IndexSearcher indexSearcher = getIndexSearcher();
    //false是不包含左边区间,true是包含右边区间
    Query query = NumericRangeQuery.newLongRange("fileSize", 47L, 200L, false, true);
    System.out.println(query);
    printResult(indexSearcher, query);
    //关闭资源
    indexSearcher.getIndexReader().close();
}

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

1.8. 使用解析查询

  1. 利用QueryParser查询
//条件解释的对象查询
@Test
public void testQueryParser() throws Exception {
    IndexSearcher indexSearcher = getIndexSearcher();
    //参数1: 默认查询的域  
    //参数2:采用的分析器
    QueryParser queryParser = new QueryParser("fileName",new IKAnalyzer());
    // *:*   域:值
    Query query = queryParser.parse("fileName:lucene is apache OR fileContent:lucene is apache");

    printResult(indexSearcher, query);
    //关闭资源
    indexSearcher.getIndexReader().close();
}

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

猜你喜欢

转载自blog.csdn.net/qq_33322074/article/details/89929836