2014-09-17 2 views
7

Кажется, что всякий раз, когда я обновляю существующий документ в индексе (такое же поведение для delete/add), его нельзя найти с помощью TermQuery. Вот короткий фрагмент:Lucene не может найти документы после обновления

iw = new IndexWriter (directory, config);

Document doc = new Document(); 
doc.add(new StringField("string", "a", Store.YES)); 
doc.add(new IntField("int", 1, Store.YES)); 

iw.addDocument(doc); 

Query query = new TermQuery(new Term("string","a")); 

Document[] hits = search(query); 
doc = hits[0]; 
print(doc); 

doc.removeField("int"); 
doc.add(new IntField("int", 2, Store.YES)); 

iw.updateDocument(new Term("string","a"), doc); 

hits = search(query); 
System.out.println(hits.length); 
System.out.println("_________________"); 

for(Document hit : search(new MatchAllDocsQuery())){ 
    print(hit); 
} 

Это производит следующий вывод на консоль:

stored,indexed,tokenized,omitNorms,indexOptions=DOCS_ONLY<string:a> 
stored<int:1> 
________________ 
0 
_________________ 
stored,indexed,tokenized,omitNorms,indexOptions=DOCS_ONLY<string:a> 
stored<int:2> 
________________ 

Похоже, что после обновления, документ (а новый документ) в индексе и получает возвращаемый MatchAllDocsQuery, но не может можно найти в TermQuery.

Полный пример кода доступен на http://pastebin.com/sP2Vav9v

Кроме того, это происходит только (второй поиск не работает), если значение Стрингфилд содержит специальные символы (например, файл:/F: /).

+1

Вы не пропустите 'iw.commit()'? – mindas

+0

Ничего не меняет. Пробовал это aleady. Кроме того, поиск открывает новый читатель от автора каждый раз: DirectoryReader reader = DirectoryReader.open (iw, true); – Michael

+0

Кажется, я сталкиваюсь с подобной проблемой. Какая версия Lucene это? – carlspring

ответ

4

Код, на который вы ссылаетесь в pastebin, не находит ничего, потому что ваш StringField - не что иное, как секундомер (a). Замена a с чем-то, что не является секундомером (например, ax), приводит к тому, что оба запроса возвращают 1 документ.

Вы также добиться правильного результата, если вы должны были построить StandardAnalyzer с пустым множеством (CharArraySet.EMPTY_SET стоп-слов) еще до сих пор используют a для StringField. Однако это не сработало бы для file:/F:/.

Тем не менее, лучшим решением является в этом случае заменить StandardAnalyzer на KeywordAnalyzer.

+0

Я думал, что StringField не анализируется? Кроме того, как происходит обновление этого эффекта, но вставить новый документ нет? – Michael

+0

'StringField' не анализируется, это правильно. Но фильтр останова по-прежнему применяется - см. «StandardAnalyzer» Javadoc. Lucene в книге действий (стр. 120-121) говорит: «« StandardAnalyzer »также включает снятие паузы». Что касается обновления/вставки вопроса - я не совсем уверен. Я попытаюсь отладить и опубликовать результаты, если найду. – mindas

1

Я мог бы избавиться от этого путем воссоздания моего рабочего каталога после всех операций индексирования: создать новый каталог только для этих операций индексирования с именем «path_dir», например. Если вы обновили, выполните следующие операции и повторите все предыдущие работы.

StandardAnalyzer analyzer = new StandardAnalyzer(Version.LUCENE_46); 
FSDirectory dir; 
try { 
    // delete indexing files : 
    dir = FSDirectory.open(new File(path_dir)); 
    IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_46, analyzer); 
    IndexWriter writer = new IndexWriter(dir, config); 
    writer.deleteAll(); 
    writer.close(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

Однако обратите внимание, что этот способ будет очень медленным, если вы обрабатываете большие данные.

+0

Как это точно «исправить»? Удаление индекса абсолютно смешно! Что произойдет, если вам нужно обновить 10 000 000 записей пять раз, и вам нужно каждый раз удалять индекс? Это неприемлемо. – carlspring

+0

Я уже прокомментировал большие данные в конце моего ответа. Я мог бы заставить мой код работать нормально. Поскольку я не обрабатываю большие данные, это не проблема для меня. Если у Майкла также есть небольшие данные, это может сработать. – balik

Смежные вопросы