在Luecne中,没有方法对已经被索引的Document进行更新,唯一的办法就是讲原有的Document对象删除,然后写入一个新的Document。
在IndexReader中提供了两个方法来删除Document :
public final void deleteDocument(int docNum) throws IOException
public final int deleteDocuments(Term term) throws IOException
(注:在1.4的Lucene中分别为delete(int docNum)和delete(Term term)
对于一个document被删除之后,它只是在TermDocs 或者TermPositions enumerations 中不会被出现,但是并没有真正的被删除,这个时候试图用方法document(int)方法读取document的field就会出错,但是The presence of this document may still be reflected in the docFreq(org.apache.lucene.index.Term) statistic, though this will be corrected eventually as the index is further modified.
但是这个方法在实际的应用中就显得麻烦,因为你很难知道一个document的docNum,从而就不能用这个方法去删除document。
这个时候就会选择第二个方法,它会删除包含term的所有的document,要使的这个方法每次只删除一个document,简单的做法就是在document的中加一个有着唯一的ID的field,那么在删除这个document的时候就用这个方法deleteDocuments(new Term("xx_ID",xx.getID()); 这样就可以删除对应的document,然后加进去新的document。
但是在写代码的过程中我还是遇到了没有办法删除document对象的状况。在确定不是参数有问题的情况下,我的第一反应是,对同一个索引打开了一个IndexWriter和一个IndexReader,在IndexReader删除的时候,IndexWriter还没有关闭,我怀疑有写锁的存在(PS:关于Lucene的线程安全性还没有仔细看呢),但是独立写了个测试,发现这不是问题的所在。
我用 deleteDocument(int docNum) 确成功的删除了document,那么是什么导致deleteDocuments(Term term)没有办法删除呢??
仔细检查了一下,发现1.4版本中的示例代码中是这样的
doc.add(Field.Text("name","Word1 word2 word3"));
reader.delete(new Term("name","word1"));
而我的代码中是doc.add(new Field("xx_ID",xx.getID(),Field.Store.YES,Field.Index.NO));
而在1.4中Field.Text()是将字段切词,索引,存储的
!!!!!!!!!所以我将代码改为Field.Index.UN_TOKENIZD再测试就没有问题了,顺利将document删除了。分析原因,把lucene的源代码下了下来,没看之前的想法是,它要删除包含这个term的document可能调用类似search的方法,而我没有将这个ID的field索引打开,可能就导致搜索不到这个document。(PS:只是乱想)
源代码还是很烦,不是一下就能看明白,以后再说~~~~
有一个简单的认识:
termDocs()实现的是Term => <docNum, freq, <pos1, pos2, ... posfreq-1> >*
这样一个映射,也许这两个删除的方法都是由protected abstract void doDelete(int docNum) throws IOException 这个方法真正实现的(PS:猜测而已),也许问题的入口就在如何构建到这个映射关系的,看了代码之后再慢慢想。
分享到:
相关推荐
《Lucene实战源码(Lucene in Action Source Code)part2》是针对知名搜索库Lucene的一份重要学习资源,其包含的是书籍《Lucene in Action》中的实践代码,主要聚焦于Lucene的深入理解和应用。这个压缩包的第二部分...
1. **文档(Document)**:在Lucene中,文档是信息的基本单位,可以代表网页、电子邮件或者其他形式的数据。文档由一系列字段(Field)组成,每个字段有名称和内容,比如标题、正文等。 2. **字段(Field)**:字段...
public void deleteDocument(String id) {...} } public class QueryParser { public Query parse(String queryText) {...} } public class SearchService { public List<ResultItem> search(Query query, int ...
在Lucene中,删除操作通常是通过添加删除标记(Delete Query)完成的,而不是立即物理删除,以确保在并发环境下的一致性。更新文档则涉及创建新的文档版本并重新索引,旧的版本会在后台被清理。 索引的参数调整是另...
foreach (var hit in hits.ScoreDocs) { var doc = searcher.Doc(hit.Doc); Console.WriteLine($"Title: {doc.Get("Title")}, Content: {doc.Get("Content")}"); } } ``` **四、索引删除** 删除整个索引时,...
这个“lucene增删改查小demo”涵盖了 Lucene 搜索库的基础操作,通过 IndexWriter 进行索引管理,使用 QueryParser 构建查询,IndexSearcher 执行查询,并通过 Document 实现数据的读写。掌握这些基本操作后,你可以...
import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.Term; import org.apache.lucene....
- `deleteDocument(String id)`: 删除指定 ID 的文档。 - `search(String queryStr)`: 根据查询字符串返回匹配的 Document 列表。 5. **查询结果处理** - **ScoreDoc**: 搜索结果由 ScoreDoc 类表示,包含了文档...
- **删除(Delete)**:通过文档 ID 或者 Term(关键词)来删除索引中的文档。使用 `IndexWriter.deleteDocuments(Term)` 方法可以按关键词删除,`IndexWriter.deleteDocuments(Document)` 则按文档对象删除。 - *...
- 当调用`IndexWriter.deleteAll()`方法时,Lucene会创建一个名为`write.lock`的文件来锁定原索引文件,防止其他进程同时修改索引。该文件通常存储在索引目录中。 - 如果锁目录与索引目录不同,则写锁文件名会带有...
8. **更新与删除(Update & Delete)**:Lucene允许动态地更新或删除索引中的文档,但要注意这可能导致索引碎片,需要定期进行优化(`Optimize`)操作以保持最佳性能。 9. **多线程支持**:Lucene设计时考虑了多...
3. **文档(Document)**:在Lucene中,文档是存储信息的基本单位,可以包含多个字段(Field),每个字段有其特定的属性,如是否可搜索、是否存储原始内容等。 4. **字段(Field)**:字段用于组织文档内容,如标题...
- **deleteAll()**:删除所有文档与索引。 - **deleteDocuments(Term term)**:删除指定文档与索引。 - **updateDocument(Term term, Document doc)**:更新指定文档与索引。 - **commit()**:提交更改。 - **...
- `IndexReader.deleteDocument(int docID)`:通过文档编号删除文档,立即对当前`IndexReader`生效。 - `IndexReader.deleteDocuments(Term term)`:删除包含特定词的文档,同样立即生效。 - `IndexWriter....
1. 若要删除索引库中的所有索引,可使用IndexWriter对象的deleteAll()方法。 2. 若要删除索引库中的特定文档,首先需要创建一个查询对象,如TermQuery,指定要删除的文档的属性和值。然后使用IndexWriter对象的...
indexWriter.deleteAll(); // 访问数据库取得数据 ResultSet rs = wenjian.getWenjians(); while (rs.next()) { Document doc = new Document(); int id = rs.getInt(1); Integer Id = new Integer(id); doc...
《Lucene CRUD操作详解》 在信息技术领域,搜索引擎技术扮演着至关重要的角色,Apache Lucene就是这样一款强大的全文搜索引擎库。本篇文章将深入探讨如何在Java环境中,利用Hibernate和Struts2框架实现Lucene的CRUD...
在“Lucene 实现控制台操作 C/R/U/D”这一主题中,我们将深入探讨如何利用 Lucene 来完成创建(Create)、读取(Read)、更新(Update)和删除(Delete)这四个基本数据库操作在文本搜索中的应用。 1. **创建...
Lucene的索引建立可以通过IndexWriter类实现,IndexWriter类提供了多种方法来建立索引,包括addDocument方法、updateDocument方法、deleteDocument方法等。 Lucene的查询可以通过Searcher类实现,Searcher类提供...
- **文档(Document)**:文档是Lucene处理的基本单位,可以包含多个字段(Field),如标题、正文等。 - **字段(Field)**:每个文档由一个或多个字段组成,每个字段都有特定的属性,如是否可搜索、是否存储等。 - ...