由于分词工具用的用户字典有了更新,比如加入了一些出现频度较高的专有名词。
这时候希望通过重建索引,使查询结果更加准确。
但是,由于一些信息是当初建索引时加入的,而且这些信息是不能从原始文件中提取的,如当初的上传者是谁、上传日期 等。所以,不能够直接删除索引文件,重新来过。
为此,必须遍历原有索引,将其中进行了分析的Field重新分析并更新,不需要分析的Field则保持不变。
/**
* 为现有文件重新创建索引
* 例如当更新了用户字典时使用
*/
public void rebuildIndex(){
IndexReader ireader = null;
IndexWriter iwriter = null;
Directory directory = null;
try {
long start = new Date().getTime();
//前期准备工作
File indexPath = new File(SystemProperties.getIndexPath());
directory = FSDirectory.open(indexPath);
//实例化IKAnalyzer分词器
Analyzer analyzer = new IKAnalyzer();
//Analyzer analyzer = new CJKAnalyzer(Version.LUCENE_CURRENT);
//建立内存索引对象
ireader = IndexReader.open(directory);
if (indexPath.list().length > 0) {
// 已有以往索引
iwriter = new IndexWriter(directory, analyzer, false, IndexWriter.MaxFieldLength.LIMITED);
} else {
// 首次建立索引
iwriter = new IndexWriter(directory, analyzer, true, IndexWriter.MaxFieldLength.LIMITED);
}
//遍历每一已有Document
for (int i = 0; i < ireader.maxDoc(); i++) {
try {
// 提取原Document
Document oldDoc = ireader.document(i);
// 创建新Document
Document newDoc = new Document();
// 不变的Field直接从原Document中取
// KEY
newDoc.add(oldDoc.getField(Constants.FEILD_NAME_KEY));
// 文件名
newDoc.add(oldDoc.getField(Constants.FEILD_NAME_CLIENTNAME));
newDoc.add(oldDoc.getField(Constants.FEILD_NAME_SERVERNAME));
// 文件类型
newDoc.add(oldDoc.getField(Constants.FEILD_NAME_FILETYPE));
// 加入时间
newDoc.add(oldDoc.getField(Constants.FEILD_NAME_ADDTIME));
// 所属部门,用户查询时的权限控制
newDoc.add(oldDoc.getField(Constants.FEILD_NAME_OWNER));
// 不变的Field从原Document中取得后,重新Analyse
// 标题
String title = oldDoc.getField(Constants.FEILD_NAME_TITLE).stringValue();
newDoc.add(new Field(Constants.FEILD_NAME_TITLE, title, Field.Store.YES, Field.Index.ANALYZED));
// 内容
String text = oldDoc.getField(Constants.FEILD_NAME_CONTENTS).stringValue();
newDoc.add(new Field(Constants.FEILD_NAME_CONTENTS, text, Field.Store.YES, Field.Index.ANALYZED));
String key = oldDoc.getField(Constants.FEILD_NAME_KEY).stringValue();
// 用KEY做查询条件
Term term = new Term(Constants.FEILD_NAME_KEY, key);
// 替换原有的Document
iwriter.updateDocument(term, newDoc);
} catch (Throwable t) {
if (log.isErrorEnabled()) {
log.error(t.getMessage());
}
}
}
long end = new Date().getTime();
if (log.isDebugEnabled()) {
log.debug("Rebuild Index: " + ireader.maxDoc() + " documents, in " + (end - start) + " milliseconds.");
}
} catch (Throwable t) {
if (log.isErrorEnabled()) {
log.error(t.getMessage());
}
} finally {
if (ireader != null) {
try {
ireader.close();
} catch (AlreadyClosedException e) {
log.error(e.getMessage());
} catch (IOException e) {
log.error(e.getMessage());
}
}
if (iwriter != null) {
try {
// 注意这一句非常重要,否则虽然效果已经达到,但Documents数和存储空间都会翻倍!
// 但使用此方法的前提是,磁盘剩余空间必须有已用索引空间的2倍
// 此时由于重建,索引空间已经是翻倍的了,所以剩余空间应该有之前索引空间的4被!
iwriter.optimize();
iwriter.close();
} catch (AlreadyClosedException e) {
log.error(e.getMessage());
} catch (IOException e) {
log.error(e.getMessage());
}
}
if (directory != null) {
try {
directory.close();
} catch (IOException e) {
log.error(e.getMessage());
}
}
}
}
刚刚接触Lucene时间不长,不知道以上自己“杜撰”的代码是否可行,请大家多多指点。
- 大小: 3.2 KB
- 大小: 622 Bytes
分享到:
相关推荐
索引更新是Lucene中的一种重要机制,用于实时更新索引中的文档。索引更新可以分为两种情况:删除文档和更新文档。在Lucene中,删除文档可以使用IndexReader和IndexWriter两种方式实现,每种方式都有其优缺。 首先,...
这个方法会先检查每个待插入对象是否已存在于数据库中,如果存在则调用 `updateById()` 进行更新,否则调用父类的 `batchInsert()` 方法进行插入。 对于批量更新,情况类似,但通常不需要检查数据是否存在,因为...
但每个表只能有一个聚集索引,因为目录只能按照一种方法进行排序。 非聚集索引是目录纯粹是目录,正文纯粹是正文的排序方式。非聚集索引需要两个过程,先找到目录中的结果,然后再翻到所需的页码。非聚集索引的缺点...
这种方法允许你在不删除旧索引的基础上重新创建它,减少了重建过程中的开销。当你对聚集索引执行此操作时,通常会涉及到所有关联的非聚集索引。如果直接删除并重新创建聚集索引,那么所有的非聚集索引都需要被删除...
本文将深入探讨“索引维护方法”,并基于提供的描述和标签,讲解如何在Microsoft SQL Server环境中有效地进行索引维护。 首先,索引是数据库中的一个重要组成部分,它类似于书籍的目录,能够加速数据检索过程。索引...
Oracle索引的访问方法和创建索引的知识点 Oracle索引的访问方法是一种数据库优化技术,旨在提高查询速度和数据检索效率。索引是一种数据结构,它可以快速定位和检索数据库中的数据。Oracle索引的访问方法包括创建...
- 索引更新时,应避免在搜索操作进行时修改索引,以防止数据不一致。 - 为了提高搜索效率,可以在创建索引时设置适当的参数,如`IndexWriterConfig`的`OpenMode`(决定是否覆盖现有索引)和`IndexingOptions`(决定...
通过以上测试结果,我们可以看到,Solr 数据库插入全量和增量索引可以正确地将数据插入 Solr 索引库中,并且可以实时地更新索引。在实际应用中,我们可以根据实际情况选择全量索引或增量索引,以满足不同的业务需求...
1. **资料的准确性**:由于网络上的信息繁多且质量参差不齐,使用Lucene时要确保所参考的教程或文档是最新的,因为版本更新可能导致某些方法或功能的改变。例如,旧版本中可能使用的`Hits`类在新版本中已被废弃,应...
实验结果表明,在处理高并发更新和数据分布不均的场景中,GAPI技术较传统索引方法有着明显的性能提升。具体来说,GAPI展现了更高的数据处理吞吐量和更低的系统响应时间,尤其在对象分布不均匀的环境下,性能优势更为...
在电信设备上,由于数据量庞大且实时性要求高,如何快速、有效地更新索引信息就显得尤为重要。 索引信息的更新涉及到两个主要方面:一是新数据的引入,二是旧数据的修改或删除。当新的电信数据产生时,全文检索系统...
"SQL Server 2000 索引结构及使用方法" 本文将详细介绍 SQL Server 2000 的索引结构和使用方法,包括聚集索引和非聚集索引的定义、区别、使用场景和注意事项。 一、索引结构 索引是一种特殊的目录,可以帮助我们...
通过学习和理解这个Rtree索引方法的C++源代码,开发者可以深入掌握空间索引技术,提高处理大量多维数据时的性能,这对于开发地理信息系统软件、数据库索引优化或任何涉及空间查询的应用都是极其有价值的。
本文将深入探讨当前XML索引技术的研究现状,分析现有索引方法的优点与不足,并展望未来的研究方向。 #### 二、XML索引技术概述 根据孔令波等人的研究,XML索引技术主要可以分为两大类:节点记录类索引和结构摘要类...
索引的失效场景包括:更新或删除索引列,使用不带索引的全表扫描操作,使用`SELECT *`而不是明确列出索引列,使用`NOT IN`、`<> ALL()`或`NOT EXISTS`等操作,以及在`WHERE`子句中使用了函数或表达式。此外,索引也...
5. **合并索引**:所有线程完成索引后,使用IndexWriter的`addIndexes()`方法将所有子索引合并到一个主索引中。 这个过程需要注意线程同步问题,确保在合并索引之前,所有线程已经完成了它们的工作,避免并发冲突。...
为应对这些挑战,本文将深入探讨一种创新的解决方案——“融合哈希的频繁更新不确定移动对象索引方法”。 在开始具体讨论之前,先让我们明确什么是“不确定移动对象”。在现实应用中,不确定移动对象通常指的是那些...
- 注意索引维护:重建或重新组织索引以保持其性能。 4. **全文搜索**: - 全文搜索允许对文本字段进行复杂的模糊匹配和自然语言搜索,对提供高级搜索体验非常有用。 5. **平衡索引策略**: - 在`custid`和`city...
数据库中的索引是一种为了加速数据查询而创建的数据结构,它为表中的字段提供了一种快速访问的方法。在没有索引的情况下,数据库系统执行查询时必须进行全表扫描,即逐行检查直到找到所需数据,这在数据量大时效率极...
如果未在索引中找到,可能需要进行全序列查找,或者更新索引结构。 4. **优化策略**:在某些情况下,如果索引不能精确定位到目标,可以采用分块索引或多级索引等技术,进一步提高查找效率。 在提供的文件中,"索引...