03. lucene索引库的维护

lucene索引库的维护

一、常用的域 field 的使用

1). 关键名词

  1. 是否分析:是否对域的内容进行分词处理。前提是我们要对域的内容进行查询。
  2. 是否索引:将Field分析后的词或整个Field值进行索引,只有索引方可搜索到。比如:商品名称、商品简介分析后进行索引,订单号、身份证号不用分析但也要索引,这些将来都要作为查询条件。
  3. 是否存储:将Field值存储在文档中,存储在文档中的Field才可以从Document中获取,比如:商品名称、订单号,凡是将来要从Document中获取的Field都要存储。

是否存储的标准:是否要将内容展示给用户

2). 各个域的比较

Field类 数据类型 Analyzed是否分析 Indexed是否索引 Stored是否存储 说明
StringField(FieldName, FieldValue,Store.YES或者Store.NO)) 字符串 N Y Y或N 这个Field用来构建一个字符串Field,但是不会进行分析,会将整个串存储在索引中,比如(订单号,姓名等),是否存储在文档中用Store.YES或Store.NO决定
LongPoint(String name, long... point) Long型 Y Y N 可以使用LongPoint、IntPoint等类型存储数值类型的数据。让数值类型可以进行索引。但是不能存储数据,如果想存储数据还需要使用StoredField。
StoredField(FieldName, FieldValue) 重载方法,支持多种类型 N N Y 这个Field用来构建不同类型Field,不分析,不索引,但要Field存储在文档中
TextField(FieldName, FieldValue, Store.YES或者Store.NO)或TextField(FieldName, reader) 字符串 或 流 Y Y Y或N 如果是一个Reader, lucene猜测内容比较多,会采用Unstored的策略.

二、添加文档

添加文档和创建索引库的步骤如出一辙,注意:不同的文档是可以有不同的域的! 存储不存储是不影响查询的

// 创建一个IndexWriter对象,需要使用IKAnalyzer作为分析器
IndexWriter indexWriter = new IndexWriter(
        FSDirectory.open(new File("E:\\lucene_repository\\rep_01").toPath()),
        new IndexWriterConfig(new IKAnalyzer()));


// 读取磁盘上需要添加的文件
File file = new File("F:\\03Web开发\\03_lucene\\02.参考资料\\searchsource\\spring.txt");

// 创建一个Docunment对象
Document document = new Document();

// 向document中添加域
document.add(new TextField("filename", file.getName(), Field.Store.YES));
document.add(new TextField("contect", FileUtils.readFileToString(file, "utf-8"), Field.Store.YES));
document.add(new StoredField("size", FileUtils.sizeOf(file)));

// 将文档写入索引库
indexWriter.addDocument(document);

// 关闭索引库
indexWriter.close();

三、删除索引库

1). 删除所有文档对象 Document

// 创建一个IndexWriter对象,这里使用IKAnalyzer作为分析器
IndexWriter indexWriter = new IndexWriter(
        FSDirectory.open(new File("E:\\lucene_repository\\rep_01").toPath()),
        new IndexWriterConfig(new IKAnalyzer()));

// 删除全部文档
indexWriter.deleteAll();

// 关闭索引库
indexWriter.close();

2). 根据查询针对性删除文档对象 Document

IndexWriter indexWriter = new IndexWriter(
        FSDirectory.open(new File("E:\\lucene_repository\\rep_01").toPath()),
        new IndexWriterConfig(new IKAnalyzer()));

// 将name域中包含有 php 的文档对象Document删除
indexWriter.deleteDocuments(new Term("name", "php"));

indexWriter.close();

四、更新索引库

更新的原理是 先删除 后添加

IndexWriter indexWriter = new IndexWriter(
        FSDirectory.open(new File("E:\\lucene_repository\\rep_01").toPath()),
        new IndexWriterConfig(new IKAnalyzer()));

// 创建一个新的文档用于替换被查询的文档集合
Document document = new Document();

// 向文档中添加域
document.add(new TextField("name", "filename", Field.Store.YES));
document.add(new TextField("context", "file content", Field.Store.YES));

// 更新替换操作
// 第一个为查询被替换的文档集合,第二个参数为一个文档
indexWriter.updateDocument(new Term("name"), document);

/* 下面的方式的第二个参数可以写一个可迭代的集合
indexWriter.updateDocuments(new Term("name"), documents);
*/

// 关闭索引库
indexWriter.close();

五、索引库的查询

1). TermQuery(Query的子类)

根据关键字进行查询,需要执行查询的域以及要查询的关键字
全文检索lucene创建索引库

2). 范围查询(Query的子类)

范围查询,针对 LongPoint

//1. 创建一个Director对象,指定索引库的位置
Directory directory = FSDirectory.open(new File("E:\\lucene_repository\\rep_01").toPath());

//2. 创建一个IndexReader对象
IndexReader indexReader = DirectoryReader.open(directory);

//3. 创建一个IndexSearcher对象,构造方法中的参数indexReader对象。
IndexSearcher indexSearcher = new IndexSearcher(indexReader);

//4. 创建一个Query对象,rangeQuery, 第一个为域,第二、三个参数为范围
Query query = LongPoint.newRangeQuery("size", 0L, 100L);

//5. 执行查询,得到一个TopDocs对象
// 参数1: 查询对象; 参数2:限制查询结果返回的最大记录数,
TopDocs topDocs = indexSearcher.search(query, 10);

//6. 取查询结果的总记录数
System.out.println("查询的总记录数:" + topDocs.totalHits);

//7. 取文档列表
ScoreDoc[] scoreDocs = topDocs.scoreDocs;

//8. 打印文档中的内容
for (ScoreDoc doc : scoreDocs) {
    // 取文档id
    int docId = doc.doc;

    // 根据id获取文档对象
    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("--------------------------------");
}

//9. 关闭IndexReader对象。
indexReader.close();

3). QueryParser 进行查询

可以对要查询的内容先分词,然后基于分词的结果进行查询。

  1. 需要添加一个jar包:lucene-queryParser-7.4.0.jar
  2. maven坐标

    org.apache.lucene
    lucene-queryparser
    7.4.0

  1. 查询示例
//1. 创建一个Director对象,指定索引库的位置
Directory directory = FSDirectory.open(new File("E:\\lucene_repository\\rep_01").toPath());

//2. 创建一个IndexReader对象
IndexReader indexReader = DirectoryReader.open(directory);

//3. 创建一个IndexSearcher对象,构造方法中的参数indexReader对象。
IndexSearcher indexSearcher = new IndexSearcher(indexReader);

//4. 创建一个QueryParser对象,两个参数
// 参数1:默认搜索域,参数2:分析器对象
QueryParser queryParser = new QueryParser("name", new IKAnalyzer());

Query query = queryParser.parse("lucene是一个Java开发的全文检索工具包");

//5. 执行查询,得到一个TopDocs对象
// 参数1: 查询对象; 参数2:限制查询结果返回的最大记录数,
TopDocs topDocs = indexSearcher.search(query, 10);

//6. 取查询结果的总记录数
System.out.println("查询的总记录数:" + topDocs.totalHits);

//7. 取文档列表
ScoreDoc[] scoreDocs = topDocs.scoreDocs;

//8. 打印文档中的内容
for (ScoreDoc doc : scoreDocs) {
    // 取文档id
    int docId = doc.doc;

    // 根据id获取文档对象
    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("--------------------------------");
}

//9. 关闭IndexReader对象。
indexReader.close();

你可能感兴趣的:(03. lucene索引库的维护)