gpt4 book ai didi

java - 如何保留Lucene索引而不删除文档

转载 作者:太空宇宙 更新时间:2023-11-04 06:25:50 25 4
gpt4 key购买 nike

这是我在 Stack Overflow 上的第一个问题,祝我好运。

我正在使用 java 对 Lucene 索引进行分类过程,并且需要更新名为类别的文档字段。我一直在使用 Lucene 4.2 和索引编写器 updateDocument() 函数来实现此目的,并且它工作得很好,除了删除部分。即使我在更新后使用forceMergeDeletes()函数,索引也会显示一些已删除的文档。例如,如果我对包含 1000 个文档的索引运行分类,则索引中的最终文档数量保持不变并按预期工作,但当我将索引文档增加到 10000 时,索引会显示一些已删除的文档,但不是全部。那么,我怎样才能真正从索引中删除那些已删除的文档呢?

这是我的代码的一些片段:

public static void main(String[] args) throws IOException, ParseException {
///////////////////////Preparing config data////////////////////////////
File indexDir = new File("/indexDir");
Directory fsDir = FSDirectory.open(indexDir);

IndexWriterConfig iwConf = new IndexWriterConfig(Version.LUCENE_42, new WhitespaceSpanishAnalyzer());
iwConf.setOpenMode(IndexWriterConfig.OpenMode.APPEND);
IndexWriter indexWriter = new IndexWriter(fsDir, iwConf);

IndexReader reader = DirectoryReader.open(fsDir);
IndexSearcher indexSearcher = new IndexSearcher(reader);
KNearestNeighborClassifier classifier = new KNearestNeighborClassifier(100);
AtomicReader ar = new SlowCompositeReaderWrapper((CompositeReader) reader);

classifier.train(ar, "text", "category", new WhitespaceSpanishAnalyzer());

System.out.println("***Before***");
showIndexedDocuments(reader);
System.out.println("***Before***");

int maxdoc = reader.maxDoc();
int j = 0;
for (int i = 0; i < maxdoc; i++) {
Document doc = reader.document(i);
String clusterClasif = doc.get("category");
String text = doc.get("text");
String docid = doc.get("doc_id");
ClassificationResult<BytesRef> result = classifier.assignClass(text);
String classified = result.getAssignedClass().utf8ToString();

if (!classified.isEmpty() && clusterClasif.compareTo(classified) != 0) {
Term term = new Term("doc_id", docid);
doc.removeField("category");
doc.add(new StringField("category",
classified, Field.Store.YES));
indexWriter.updateDocument(term,doc);
j++;
}
}
indexWriter.forceMergeDeletes(true);
indexWriter.close();
System.out.println("Classified documents count: " + j);
System.out.println();
reader.close();

reader = DirectoryReader.open(fsDir);
System.out.println("Deleted docs: " + reader.numDeletedDocs());
System.out.println("***After***");
showIndexedDocuments(reader);
}

private static void showIndexedDocuments(IndexReader reader) throws IOException {
int maxdoc = reader.maxDoc();
for (int i = 0; i < maxdoc; i++) {
Document doc = reader.document(i);
String idDoc = doc.get("doc_id");
String text = doc.get("text");
String category = doc.get("category");

System.out.println("Id Doc: " + idDoc);
System.out.println("Category: " + category);
System.out.println("Text: " + text);
System.out.println();
}
System.out.println("Total: " + maxdoc);
}

我花了很多时间寻找解决方案,有人说索引中删除的文档并不重要,当我们不断向索引添加文档时它们最终会被删除,但我需要以一种可以随时迭代索引文档的方式控制该过程,并且我检索到的文档实际上是 Activity 的文档。 Lucene 4.0 之前的版本在 IndexReader 类中有一个名为 isDeleted(docId) 的函数,该函数给出文档是否已标记为已删除的信息,这可能只是解决我的问题的一半,但我还没有找到使用 Lucene 4.2 版本来做到这一点的方法。如果您知道如何做到这一点,我将非常感谢您分享它。

最佳答案

可以检查是否有文档被删除是MultiFields类,例如:

Bits liveDocs = MultiFields.getLiveDocs(reader);
if (!liveDocs.get(docID)) ...

因此,将其应用到您的代码中,也许类似于:

int maxdoc = reader.maxDoc();
Bits liveDocs = MultiFields.getLiveDocs(reader);
for (int i = 0; i < maxdoc; i++) {
if (!liveDocs.get(docID)) continue;
Document doc = reader.document(i);
String idDoc = doc.get("doc_id");
....
}

顺便说一句,听起来您之前一直在使用 3.X,现在正在使用 4.X。 The Lucene Migration Guide对于理解版本之间的这些变化以及如何解决它们非常有帮助。

关于java - 如何保留Lucene索引而不删除文档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26805297/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com