我正在使用Lucene.NET进行项目,并且创建索引/搜索索引非常棒。但是,当我更新时,我似乎只添加到搜索索引,但从来没有删除条款。从头开始重建索引可以修复问题,但显然我不希望每次修改某个值时都不这样做。
这是我用来更新文档的方法(更改类名以保护无辜者):
internal static void ModifyDocuments(IEnumerable<SomeFancyObject> changed)
{
if (changed.Count() == 0) {
return;
}
var dir = FSDirectory.Open(LuceneGlobals.directory);
var writer = new IndexWriter(dir, LuceneGlobals.analyzer, false, new IndexWriter.MaxFieldLength(int.MaxValue));
foreach (var fancyObj in changed) {
//writer.DeleteDocuments(new Term("fancyID", fancyObj.ID.ToString()));
//writer.AddDocument(CreateDocument(fancyObj));
writer.UpdateDocument(new Term("fancyID", fancyObj.ID.ToString()), CreateDocument(index));
}
writer.Optimize();
writer.Close();
}
请注意,我已经尝试了所写的代码,并且还注释了删除/添加代替更新调用。我还尝试writer.Commit();
代替writer.Optimize();
。
调试显示整个方法已执行,CreateDocument()
使用我期望看到的数据创建一个新文档。以下是CreateDocument()
的完整性:
private static Document CreateDocument(SomeFancyObject fancyObj)
{
var doc = new Document();
doc.Add(new Field("docType", "SomeFancyObject", Field.Store.YES, Field.Index.NOT_ANALYZED));
doc.Add(new Field("fancyID", Convert.ToString(fancyObj.ID), Field.Store.YES, Field.Index.NO));
doc.Add(new Field("fancyText", new StringReader(fancyObj.Text)));
doc.Add(new Field("fancyTitle", new StringReader(fancyObj.Title)));
return doc;
}
我看到了我希望在fancyObj.Text
和fancyObj.Title
中看到的内容。也许我在这里没有正确使用所有选项?
需要做些什么来防止我的索引记住已更新的数据?
答案 0 :(得分:3)
您需要索引(Field.Index.NOT_ANALYZED
)fancyID。 IndexWriter.UpdateDocument
使用匹配的术语删除所有内容,但除非您将其编入索引,否则不会生成任何字词。
您还可以考虑从FieldCache中读取值,而不是存储它。