我正在使用Lucene.NET(v2.0)在Visual Basic 9(VS2008)中开发桌面搜索引擎.
我使用以下代码初始化IndexWriter
Private writer As IndexWriter writer = New IndexWriter(indexDirectory, New StandardAnalyzer(), False) writer.SetUseCompoundFile(True)
如果我选择相同的文档文件夹(包含要编制索引的文件)两次,则会在索引中创建该文档文件夹中每个文件的两个不同条目.
我希望IndexWriter丢弃索引中已存在的所有文件.
我该怎么做才能确保这一点?
正如Steve所提到的,您需要使用IndexReader的实例并调用其DeleteDocuments方法.DeleteDocuments接受Term对象的实例或Lucene的文档内部id(通常不建议尽可能使用内部id,并且会随着Lucene合并段而改变).
最好的方法是使用您存储在特定于应用程序的索引中的唯一标识符.例如,在医生办公室的患者索引中,如果您有一个名为"patient_id"的字段,您可以创建一个术语并将其作为参数传递给DeleteDocuments.请参阅以下示例(抱歉,C#):
int patientID = 12; IndexReader indexReader = IndexReader.Open( indexDirectory ); indexReader.DeleteDocuments( new Term( "patient_id", patientID ) );
然后,您可以使用IndexWriter实例再次添加患者记录.我从这篇文章中学到了很多东西http://www.codeproject.com/KB/library/IntroducingLucene.aspx.
希望这可以帮助.
有关id字段的删除有许多过时的例子.下面的代码适用于Lucene.NET 2.4.
如果您已经在使用IndexWriter或访问IndexSearcher.Reader,则无需打开IndexReader.您可以使用IndexWriter.DeleteDocuments(Term),但棘手的部分是确保您首先正确存储了您的id字段.在存储文档时,请确保使用Field.Index.NOT_ANALYZED作为id字段的索引设置.这会对字段编制索引而不对其进行标记,这非常重要,并且当使用这种方式时,其他任何Field.Index值都不会起作用:
IndexWriter writer = new IndexWriter("\MyIndexFolder", new StandardAnalyzer()); var doc = new Document(); var idField = new Field("id", "MyItemId", Field.Store.YES, Field.Index.NOT_ANALYZED); doc.Add(idField); writer.AddDocument(doc); writer.Commit();
现在,您可以使用同一个编写器轻松删除或更新文档:
Term idTerm = new Term("id", "MyItemId"); writer.DeleteDocuments(idTerm); writer.Commit();
如果要删除索引中的所有内容并重新填充,可以使用此语句
writer = New IndexWriter(indexDirectory, New StandardAnalyzer(), True)
IndexWriter构造函数的最后一个参数确定是创建新索引,还是打开现有索引以添加新文档.