【问题标题】:How to keep Lucene index without deleted documents如何在不删除文档的情况下保留 Lucene 索引
【发布时间】:2015-01-04 11:37:03
【问题描述】:

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

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

这是我的代码的一些 sn-ps:

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

我花了很多时间寻找解决方案,有人说索引中删除的文档并不重要,当我们不断向索引中添加文档时,它们最终会被删除,但我需要控制这个过程在某种程度上,我可以随时迭代索引文档,并且我检索到的文档实际上是活的。 Lucene 4.0 之前的版本在 IndexReader 类中有一个名为 isDeleted(docId) 的函数,如果文档已被标记为已删除,这可能只是解决我的问题的一半,但我还没有找到解决方法Lucene 4.2 版。如果你知道怎么做,我真的很感激你分享它。

【问题讨论】:

    标签: java lucene indexwriter


    【解决方案1】:

    你可以检查一个文件被删除的是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 对了解这些版本之间的这些变化以及如何解决它们非常有帮助。

    【讨论】:

    • 感谢您的回答。 Lucene 迁移指南也很有帮助,我会继续关注它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-05
    • 1970-01-01
    • 2016-05-22
    相关资源
    最近更新 更多