我们使用Lucene索引一些内部文档.有时我们需要删除文档.这些文档具有唯一的ID,并由类DocItem表示如下(所有代码都是简单的版本,只有重要的(我希望)部分):
public final class DocItem { public static final String fID = "id"; public static final String fTITLE = "title"; private Document doc = new Document(); private Field id = new Field(fID,"",Field.Store.YES,Field.Index.ANALYZED); private Field title = new Field(fTITLE,Field.Index.ANALYZED); public DocItem() { doc.add(id); doc.add(title); } ... getters & setters public getDoc() { return doc; } }
因此,要索引文档,将创建一个新的DocItem并将其传递给索引器类,如下所示:
public static void index(DocItem docitem) { File file = new File("indexdir"); Directory dir= new SimpleFSDirectory(file); IndexWriter idxWriter = new IndexWriter(dir,new StandardAnalyzer(Version.LUCENE_30),IndexWriter.MaxFieldLength.UNLIMITED); idxWriter.addDocument(docitem.getDoc()); idxWriter.close(); }
我们创建了一个迭代索引目录的辅助方法:
public static void listAll() { File file = new File("indexdir"); Directory dir = new SimpleFSDirectory(file); IndexReader reader = IndexReader.open(dir); for (int i = 0; i < reader.maxDoc(); i++) { Document doc = reader.document(i); System.out.println(doc.get(DocItem.fID)); } }
运行listAll,我们可以看到我们的文档被正确编入索引.至少,我们可以看到id和其他属性.
我们使用IndexSearcher检索文档,如下所示:
public static DocItem search(String id) { File file = new File("indexdir"); Directory dir = new SimpleFSDirectory(file); IndexSearcher searcher = new IndexSearcher(index,true); Query q = new QueryParser(Version.LUCENE_30,DocItem.fID,new StandardAnalyzer(Version.LUCENE_30)).parse(id); TopDocs td = searcher.search(q,1); scoreDoc[] hits = td.scoreDocs; searcher.close(); return hits[0]; }
因此,在检索它之后,我们尝试删除它:
public static void Delete(DocItem docitem) { File file = new File("indexdir"); Directory dir= new SimpleFSDirectory(file); IndexWriter idxWriter = new IndexWriter(dir,IndexWriter.MaxFieldLength.UNLIMITED); idxWriter.deleteDocuments(new Term(DocItem.fID,docitem.getId())); idxWriter.commit(); idxWriter.close(); }
问题是它不起作用.永远不会删除该文档.如果我在删除后运行listAll(),文档仍然存在.我们试图使用IndexReader,没有幸运.
我们做错了什么?任何建议?我们正在使用lucene 3.0.3和java 1.6.0_24.
TIA,
短发
解决方法
我建议,使用IndexReader
DeleteDocumets,它返回删除的文件数.这将帮助您缩小是否在第一次计数时发生删除.
这相对于indexwriter方法的优点是它返回已删除的文档总数,如果没有则返回0.
另见How do I delete documents from the index?和this帖子
编辑:另外我注意到你在readonly模式下打开indexreader,你可以用false作为第二个参数更改listFiles()索引读取器open,这将允许读写,也许是错误的来源