Lucene在更新后找不到文档

时间:2014-09-17 14:00:36

标签: java lucene

似乎无论何时我更新索引中的现有文档(删除/添加的行为相同),都无法使用TermQuery找到它。这是一个简短的片段:

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

提供的完整示例代码

此外,当StringField值包含特殊字符(例如file:/ F:/)时,这只会发生(第二次搜索不起作用)。

2 个答案:

答案 0 :(得分:4)

您在pastebin中引用的代码找不到任何内容,因为您的StringField只是一个停用词(a)。将a替换为不是停用词(例如ax)的内容会使两个搜索都返回1个文档。

如果您使用空的限位词集StandardAnalyzer)构建CharArraySet.EMPTY_SET但仍然使用a StringField,您也可以获得正确的结果。但这不适用于file:/F:/

但是,最好的解决方案是将StandardAnalyzer替换为KeywordAnalyzer

答案 1 :(得分:1)

我可以通过在所有索引操作之后重新创建我的工作目录来摆脱这种情况: 为这个名为&#34; path_dir&#34;的索引操作创建一个新目录。例如。如果您已更新,请调用以下操作并再次执行所有以前的工作。

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();
    }

但请注意,如果您处理大数据,这种方式会非常慢。