shoufeng

瘦风的南墙

Lucene 07 - 对Lucene的索引库进行增删改查

数据保存在关系型数据库中, 需要实现增、删、改、查操作; 索引保存在索引库中, 也需要实现增、删、改、查操作.

1 添加索引

参考 Lucene 02 - Lucene的入门程序(Java API的简单使用) 中的内容:

图片

2 删除索引

2.1 根据Term删除索引

根据Term删除索引的步骤为:

(1) 创建分析器对象(Analyzer), 用于分词;

(2) 创建索引配置对象(IndexWriterConfig), 用于配置Lucene;

(3) 创建索引库目录对象(Directory), 用于指定索引库的位置;

(4) 创建索引写入对象(IndexWriter), 用于操作索引;

(5) 创建删除条件对象(Term);

(6) 使用IndexWriter对象, 执行删除;

(7) 释放资源.

/**
 * 根据Term删除索引
 */
@Test
public void deleteIndexByTerm() throws IOException {
    // 1.创建分析器对象(Analyzer), 用于分词
    Analyzer analyzer = new IKAnalyzer(); 

    // 2.创建索引配置对象(IndexWriterConfig), 用于配置Lucene
    IndexWriterConfig iwc = new IndexWriterConfig(Version.LUCENE_4_10_4, analyzer);

    // 3.创建索引库目录对象(Directory), 用于指定索引库的位置
    Directory directory = FSDirectory.open(new File("/Users/healchow/Documents/index"));
    
    // 4.创建索引写入对象(IndexWriter), 用于操作索引
    IndexWriter writer = new IndexWriter(directory, iwc);
    
    // 5.创建删除条件对象(Term)
    // 删除图书名称域中, 包含"java"的索引
    // delete from table where name="java"
    // 参数一: 删除的域的名称, 参数二: 删除的条件值
    Term term = new Term("bookName", "java"); 

    // 6.使用IndexWriter对象, 执行删除
    // 可变参数, 能传多个term
    writer.deleteDocuments(term);
  
   // 7.释放资源
    writer.close();
}

根据Term执行删除操作(indexWriter.deleteDocuments(term))时, 要求对应的Field不能分词且只能是一个词, 且这个Field必须索引过, Lucene将先去搜索, 然后将所有满足条件的记录删除(伪删除, 做了".del"标记) -- 最好定义一个唯一标识来做删除操作.
图片

是否删除索引, 需要分情况讨论: 我们知道, Lucene是以段(segment)来组织索引内容的, 通过Term执行删除操作(indexWriter.deleteDocuments(term))时, 若索引段中仍包含符合条件的文档对象的其他分词的索引, 就会保留整个索引数据(若采取更新操作, 则会降低性能), 如果没有, 则也将删除索引数据:
图片

查看删除了的文档的编号:
图片

2.2 删除全部索引(慎用)

删除全部索引的步骤为:

(1) 创建分析器对象(Analyzer), 用于分词;

(2) 创建索引配置对象(IndexWriterConfig), 用于配置Lucene;

(3) 创建索引库目录对象(Directory), 指定索引库位置;

(4) 创建索引写入对象(IndexWriter), 用于操作索引库;

(5) 使用IndexWriter对象, 执行删除;

(6) 释放资源.

/**
* 删除全部索引
*/
@Test
public void deleteAllIndex() throws IOException {
   // 1.创建分析器对象(Analyzer), 用于分词
   Analyzer analyzer = new IKAnalyzer();

   // 2.创建索引配置对象(IndexWriterConfig), 用于配置Lucene
   IndexWriterConfig iwc = new IndexWriterConfig(Version.LUCENE_4_10_4, analyzer);
   
   // 3.创建索引库目录对象(Directory), 用于指定索引库的位置
   Directory directory = FSDirectory.open(new File("/Users/healchow/Documents/index"));
   
   // 4.创建索引写入对象(IndexWriter), 用于操作索引
   IndexWriter writer = new IndexWriter(directory, iwc);
   
   // 5.使用IndexWriter对象, 执行删除
   writer.deleteAll();
   
   // 6.释放资源
  writer.close();
}

删除后的索引结果:
图片

删除全部索引, 将文档域的数据, 索引域的数据都删除.

类似于关系型数据库的Truncate删除: 完全删除数据, 包括存储结构, 因而更快速.

3 更新索引

Lucene是根据Term对象更新索引: 先根据Term执行查询, 查询到则执行更新, 查询不到则执行添加索引.

更新索引的步骤为:

(1) 创建分析器对象(Analyzer), 用于分词;

(2) 创建索引配置对象(IndexWriterConfig), 用于配置Lucene;

(3) 创建索引库目录对象(Directory), 用于指定索引库的位置;

(4) 创建索引写入对象(IndexWriter), 用于操作索引库;

(5) 创建文档对象(Document);

(6) 创建Term对象;

(7) 使用IndexWriter对象, 执行更新;

(8) 释放资源.

/**
 * 更新索引
 */
@Test
public void updateIndexByTerm() throws IOException{
    // 1.创建分析器对象(Analyzer), 用于分词
    Analyzer analyzer = new IKAnalyzer();
   
    // 2.创建索引配置对象(IndexWriterConfig), 用于配置Lucene
    IndexWriterConfig iwc = new IndexWriterConfig(Version.LUCENE_4_10_4, analyzer);   

    // 3.创建索引库目录对象(Directory), 用于指定索引库的位置
    Directory directory = FSDirectory.open(new File("/Users/healchow/Documents/index"));   

    // 4.创建索引写入对象(IndexWriter), 用于操作索引
    IndexWriter writer = new IndexWriter(directory, iwc);
 
    // 5.创建文档对象(Document)
    Document doc = new Document();
    doc.add(new TextField("id", "1234", Store.YES));
    // doc.add(new TextField("name", "MyBatis and SpringMVC", Store.YES));
    doc.add(new TextField("name", "MyBatis and Struts2", Store.YES)); 

    // 6.创建Term对象
    Term term = new Term("name", "SpringMVC"); 

    // 7.使用IndexWriter对象, 执行更新
    writer.updateDocument(term, doc);
   
    // 8.释放资源
    writer.close();
}

第一次执行, 由于没有查找到对应的索引, 故执行添加功能, 结果如图(不区分大小写):
图片

第二次执行时, 由于索引库中已有"name"="SpringMVC"的内容, 故执行更新操作: 将整个TextField的内容:MyBatis and Struts2添加到索引库中, 并与上次的结果合并, 结果如下图示:

图片

若第二次执行时更改了Term中name域的条件值(索引中没有对应的), 将继续执行添加功能: 将整个TextField中的内容添加到索引中.

版权声明

作者: 马瘦风

出处: 博客园 马瘦风的博客

您的支持是对博主的极大鼓励, 感谢您的阅读.

本文版权归博主所有, 欢迎转载, 但请保留此段声明, 并在文章页面明显位置给出原文链接, 否则博主保留追究相关人员法律责任的权利.

posted @ 2018-08-01 10:17  瘦风  阅读(455)  评论(0编辑  收藏  举报