Обновление Lucene.NET не удаляет условия поиска - PullRequest
2 голосов
/ 04 июня 2011

Я использую Lucene.NET для проекта, и создание индекса / поиск по индексу идет отлично. Однако при обновлении я, кажется, только добавляю к поисковому индексу, но никогда не удаляю терминов из индекса. Восстановление индекса с нуля исправляет некоторые вещи, но, очевидно, я бы предпочел не делать этого каждый раз, когда кто-то изменяет значение.

  • В качестве примера, скажем, мы проиндексировали DocumentA с полем FieldB с текстом «Это некоторый текст для индексации».
  • Поиск слова «фантастический» не дает результатов.
  • Теперь мы обновляем поле B DocumentA на «Это фантастический текст для индексации».
  • Поиск слова «фантастический» приводит к получению DocumentA (как и ожидалось).
  • Обновите поле B DocumentA до «Это какой-то посредственный текст для индексации».
  • Поиск «посредственного» приводит к получению DocumentA (как и ожидалось).
  • Поиск «фантастического» * ​​1020 * по-прежнему дает в результате DocumentA . Это не то поведение, которого я ожидаю или хочу.

Вот метод, который я использую для обновления документа (имена классов изменены, чтобы защитить невинных):

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. Возможно, я не правильно использую здесь все опции?

Что нужно сделать, чтобы мой индекс не запомнил данные, которые были обновлены?

1 Ответ

3 голосов
/ 04 июня 2011

Вам нужно индексировать (Field.Index.NOT_ANALYZED) fancyID. IndexWriter.UpdateDocument удаляет все с соответствующим термином, но никакие термины не генерируются, если вы не проиндексировали его.

Вы также можете посмотреть чтение значения из FieldCache вместо его сохранения.

...