Lucene меняется с RAMDirectory на FSDIrectory - поле содержимого отсутствует
Я просто начинающий lucene, и я застрял на проблеме во время перехода от RAMDIrectory к FSDirectory:
Сначала мой код:
private static IndexWriterConfig iwc = new IndexWriterConfig(Version.LUCENE_43,
new StandardAnalyzer(Version.LUCENE_43));
Directory DIR = FSDirectory.open(new File(INDEXLOC)); //INDEXLOC = "path/to/dir/"
// RAMDirectory DIR = new RAMDirectory();
// Index some made up content
IndexWriter writer =
new IndexWriter(DIR, iwc);
// Store both position and offset information
FieldType type = new FieldType();
type.setStored(true);
type.setStoreTermVectors(true);
type.setStoreTermVectorOffsets(true);
type.setStoreTermVectorPositions(true);
type.setIndexed(true);
type.setTokenized(true);
IDocumentParser p = DocumentParserFactory.getParser(f);
ArrayList<ParserDocument> DOCS = p.getParsedDocuments();
for (int i = 0; i < DOCS.size(); i++) {
Document doc = new Document();
Field id = new StringField("id", "doc_" + i, Field.Store.YES);
doc.add(id);
Field text = new Field("content", DOCS.get(i).getContent(), type);
doc.add(text);
writer.addDocument(doc);
}
writer.close();
// Get a searcher
IndexSearcher searcher = new IndexSearcher(DirectoryReader.open(DIR));
// Do a search using SpanQuery
SpanTermQuery fleeceQ = new SpanTermQuery(new Term("content", "zahl"));
TopDocs results = searcher.search(fleeceQ, 10);
for (int i = 0; i < results.scoreDocs.length; i++) {
ScoreDoc scoreDoc = results.scoreDocs[i];
System.out.println("Score Doc: " + scoreDoc);
}
IndexReader reader = searcher.getIndexReader();
AtomicReader wrapper = SlowCompositeReaderWrapper.wrap(reader);
Map<Term, TermContext> termContexts = new HashMap<Term, TermContext>();
Spans spans = fleeceQ.getSpans(wrapper.getContext(), new Bits.MatchAllBits(reader.numDocs()), termContexts);
int window = 2;// get the words within two of the match
while (spans.next() == true) {
Map<Integer, String> entries = new TreeMap<Integer, String>();
System.out.println("Doc: " + spans.doc() + " Start: " + spans.start() + " End: " + spans.end());
int start = spans.start() - window;
int end = spans.end() + window;
Terms content = reader.getTermVector(spans.doc(), "content");
TermsEnum termsEnum = content.iterator(null);
BytesRef term;
while ((term = termsEnum.next()) != null) {
// could store the BytesRef here, but String is easier for this
// example
String s = new String(term.bytes, term.offset, term.length);
DocsAndPositionsEnum positionsEnum = termsEnum.docsAndPositions(null, null);
if (positionsEnum.nextDoc() != DocIdSetIterator.NO_MORE_DOCS) {
int i = 0;
int position = -1;
while (i < positionsEnum.freq() && (position = positionsEnum.nextPosition()) != -1) {
if (position >= start && position <= end) {
entries.put(position, s);
}
i++;
}
}
}
System.out.println("Entries:" + entries);
}
это просто какой-то код, который я нашел на отличном веб-сайте, и я хотел попробовать… все отлично работает с использованием RAMDirectory. Но если я изменяю его на свой FSDirectory, это дает мне исключение NullpointerException вроде:
Исключение в потоке "main" java.lang.NullPointerException на com.org.test.TextDB.myMethod(TextDB.java:184) на com.org.test.Main.main(Main.java:31)
Заявление Условия content = reader.getTermVector(spans.doc(), "content"); кажется, не дает результата и возвращает ноль. так что исключение. но почему? у меня в ramDIR все отлично работает.
Кажется, что indexWriter или Reader (на самом деле не знаю) не записали или не прочитали поле "content" должным образом из индекса. Но я действительно не знаю, почему он "записан" в RAMDirectory, а не записан в FSDIrectory?!
У кого-нибудь есть идеи?
1 ответ
Я быстро провела тест, и я не могу воспроизвести вашу проблему.
Я думаю, что наиболее вероятная проблема здесь - старые документы в вашем индексе. Как это написано, каждый раз, когда он запускается, в ваш индекс будет добавляться больше документов. Старые документы из предыдущих прогонов не будут удалены или перезаписаны, они просто останутся. Итак, если вы уже запускали это в том же каталоге, скажем, возможно, прежде чем вы добавили строку type.setStoreTermVectors(true);
некоторые из ваших результатов могут быть этими старыми документами с векторами терминов, и reader.getTermVector(...)
вернет ноль, если документ не хранит векторы терминов.
Конечно, что-нибудь проиндексировано в RAMDirectory
будет сброшено, как только выполнение завершится, поэтому проблема не возникнет в этом случае.
Простым решением будет попытаться удалить каталог индекса и запустить его снова.
Если вы хотите начать с нового индекса при запуске, вы можете настроить его через IndexWriterConfig
:
private static IndexWriterConfig iwc = new IndexWriterConfig(Version.LUCENE_43,
new StandardAnalyzer(Version.LUCENE_43));
iwc.setOpenMode(IndexWriterConfig.OpenMode.CREATE);
Это предположение, конечно, но похоже на поведение, которое вы описали.