Lucene updateDocument не удаляет документы

это кажется распространенной проблемой, за исключением того, что раньше у меня не было проблем с этим, и обычное исправление не работает. Наверное, это что-то глупое, но я не могу найти.

Я хочу проиндексировать сайт yammer, так как API yammer недостаточно быстр для моей цели, проблема в том, что когда я пытаюсь обновить свой индекс с помощью функции updateDocument, старые не удаляются. Но у меня есть сохраненный уникальный ключ, который не анализируется.

Вот соответствующий код:

Document newdoc = new Document();
newdoc.add(new Field(YammerMessageFields.URL, resultUrl, Field.Store.YES, Field.Index.NOT_ANALYZED));
newdoc.add(new Field(YammerMessageFields.THREAD_ID, threadID.toString(), Field.Store.YES, Field.Index.NOT_ANALYZED));
newdoc.add(new Field(YammerMessageFields.AUTHOR, senderName, Field.Store.YES, Field.Index.ANALYZED));
newdoc.add(new Field(YammerMessageFields.CONTENTS, resultText, Field.Store.YES, Field.Index.ANALYZED));
Term key = new Term(YammerMessageFields.THREAD_ID, newdoc.getFieldable(YammerMessageFields.THREAD_ID).toString());
logger.debug("updating document with key: " + key);
try {
    IndexWriter writer = getIndexWriter();
    writer.updateDocument(key, newdoc);
    writer.close();
} catch (IOException e) {
}

Что я вижу в своем журнале:

2012-05-11 12:02:29,816 DEBUG [http-8088-2] LuceneIndex - https://www.yammer.com/api/v1/messages/?newer_than=0
2012-05-11 12:02:38,594 DEBUG [http-8088-2] LuceneIndex - updating document with key: threadid:stored,indexed<threadid:173285202>
2012-05-11 12:02:45,167 DEBUG [http-8088-2] LuceneIndex - updating document with key: threadid:stored,indexed<threadid:173033239>
2012-05-11 12:02:51,686 DEBUG [http-8088-2] LuceneIndex - updating document with key: threadid:stored,indexed<threadid:173014568>
2012-05-11 12:02:51,871 DEBUG [http-8088-2] LuceneIndex - new items:3

2012-05-11 12:03:27,393 DEBUG [http-8088-2] YammerResource - return all documents
2012-05-11 12:03:27,405 DEBUG [http-8088-2] YammerResource - nr docs:3
2012-05-11 12:03:27,405 DEBUG [http-8088-2] YammerResource - nr dels:0

...
next update
...

2012-05-11 12:03:35,802 DEBUG [http-8088-2] LuceneIndex - https://www.yammer.com/api/v1/messages/?newer_than=0
2012-05-11 12:03:43,933 DEBUG [http-8088-2] LuceneIndex - updating document with key: threadid:stored,indexed<threadid:173322760>
2012-05-11 12:03:50,467 DEBUG [http-8088-2] LuceneIndex - updating document with key: threadid:stored,indexed<threadid:173285202>
2012-05-11 12:03:56,982 DEBUG [http-8088-2] LuceneIndex - updating document with key: threadid:stored,indexed<threadid:173056406>
2012-05-11 12:04:03,533 DEBUG [http-8088-2] LuceneIndex - updating document with key: threadid:stored,indexed<threadid:173033239>
2012-05-11 12:04:10,097 DEBUG [http-8088-2] LuceneIndex - updating document with key: threadid:stored,indexed<threadid:173030769>
2012-05-11 12:04:16,629 DEBUG [http-8088-2] LuceneIndex - updating document with key: threadid:stored,indexed<threadid:173014568>
2012-05-11 12:04:23,169 DEBUG [http-8088-2] LuceneIndex - updating document with key: threadid:stored,indexed<threadid:173003570>
2012-05-11 12:04:23,341 DEBUG [http-8088-2] LuceneIndex - new items:7

2012-05-11 12:05:09,694 DEBUG [http-8088-1] YammerResource - return all documents
2012-05-11 12:05:09,696 DEBUG [http-8088-1] YammerResource - nr docs:10
2012-05-11 12:05:09,696 DEBUG [http-8088-1] YammerResource - nr dels:0

Таким образом, ключи повторяются (и 4 новых), но при этом в моем хранилище остается 10 документов вместо 7 (и 3 удаленных).

редактировать: вот как я нахожу предметы, но на самом деле я показываю их и осматриваю с Люком.

IndexReader r = IndexReader.open(searchIndex.getIndex());
                List<Document> docList = new ArrayList<Document>();
                List<Document> delList = new ArrayList<Document>();

                int num = r.numDocs();
                num += r.numDeletedDocs();
                for ( int i = 0; i < num && i < max; i++)
                {
                    if ( ! r.isDeleted( i))
                        docList.add(r.document(i));
                    else
                        delList.add(r.document(i));

                }
                r.close();
                logger.debug("nr docs:" + docList.size());
                logger.debug("nr dels:" + delList.size());

person Rhand    schedule 11.05.2012    source источник
comment
И какой вызов API используется для определения количества документов?   -  person Marko Topolnik    schedule 11.05.2012
comment
Может быть. Известно, что при вызове maxDoc удаленные документы не учитываются. Я говорю о вызове Lucene API, конечно. Ничего выше этого.   -  person Marko Topolnik    schedule 11.05.2012


Ответы (1)


Я не уверен, не запустив тестовый код, но мне это кажется неправильным:

Term key = new Term(YammerMessageFields.THREAD_ID, 
   newdoc.getFieldable(YammerMessageFields.THREAD_ID).toString());

Вы уверены, что это не должно быть:

Term key = new Term(YammerMessageFields.THREAD_ID, 
   newdoc.getFieldable(YammerMessageFields.THREAD_ID).stringValue());

Затем вы продолжаете использовать этот ключ, чтобы попытаться обновить любой соответствующий существующий документ. Если ключ неправильный, то, по-видимому, обновление документа завершится ошибкой. Я подозреваю, что toString() на этом Term на самом деле просто даст вам ссылку на объект, что означает, что обновление никогда не будет работать.

Вызов toString() для чего-либо, кроме ведения журнала или отладки (т. е. чего-либо с логикой), обычно является ошибкой.

person Jon    schedule 11.05.2012
comment
.stringValue() решил проблему. Спасибо, странно, что это работало в другой версии... - person Rhand; 11.05.2012
comment
Нет, это не так уж и странно. Программисты часто меняют реализацию toString() методов; вот почему вы никогда не должны зависеть от того, что они возвращают определенное значение. - person Jon; 11.05.2012
comment
Кстати, обновление не дало сбоев, документы действительно добавляются, просто не удается удалить. - person Rhand; 11.05.2012
comment
Обновление на самом деле представляет собой атомарное удаление/добавление — я не думаю, что в Lucene есть способ обновить документы. См. lucene.apache.org/core/old_versioned_docs/versions/3_4_0/api/, org.apache.lucene.document.Document). Там нет ничего, что говорило бы о том, что часть добавления прерывается, если удаление не соответствует каким-либо документам. Так вот - из-за отсутствия соответствующих документов заменить обновление не удается. - person Jon; 11.05.2012
comment
@Jon Есть также StringBuilder.toString, StringWriter.toString -- и целый ряд других, где toString – это API. - person Marko Topolnik; 12.05.2012
comment
@Marko Topolnik - Верно, но они являются исключением, а не правилом, и многие классы предоставляют метод, который делает то же самое, что и toString(). IMO представление toString() как части API сбивает с толку и вызывает у разработчиков вредные привычки. Если есть альтернатива, я ей пользуюсь. - person Jon; 14.05.2012
comment
@Jon Это все правильно, но, говоря с точки зрения пользователя API, не безумие думать, что вызов toString - это хорошая идея. Иногда это так, иногда нет - нельзя дать общий совет, кроме как следить за своим шагом :) Кстати, что вы имели в виду под ... даст вам ссылку на объект? Я не получил эту часть. - person Marko Topolnik; 14.05.2012
comment
@MarkoTopolnik Вы получаете напечатанную строку в соответствии со строками java.lang.Object@2687816d, которая будет использоваться по умолчанию, если вы не переопределите toString(). - person Jon; 14.05.2012
comment
Это было бы так непохоже на Lucene... это, вероятно, дает вам хорошую строку, удобную для регистратора (кажется, я помню, как использовал ее некоторое время назад...) - person Marko Topolnik; 14.05.2012
comment
Это дает вам хорошую строку, удобную для регистратора (я печатаю ее выше). - person Rhand; 15.05.2012