Lucene -如何在给定父文档ID的情况下获取父块中的所有子文档

fhity93d  于 2022-11-07  发布在  Lucene
关注(0)|答案(2)|浏览(158)

我直接使用Lucene(没有Solr或ElasticSearch)来索引一组遵循父子层次结构的文档。
我使用'blocks'来完成这一点,方法是将所有子对象和父对象添加到同一个块中,调用:

writer.addDocuments(childrenAndParentDocList)

我正在对所有父文档和子文档进行自由文本搜索(在子搜索中使用ToParentBlockJoinQuery链接到父文档),这将返回一组与查询匹配或具有与查询匹配的子文档的父文档。
接下来我需要做的事情是为我拥有的所有父文档获取所有子文档。
我在一个lucene测试here中看到过一个方法,它显示了如何在给定一个子文档的情况下获取父文档。

private Document getParentDoc(IndexReader reader, BitSetProducer parents, int childDocID) throws IOException {
    final List<LeafReaderContext> leaves = reader.leaves();
    final int subIndex = ReaderUtil.subIndex(childDocID, leaves);
    final LeafReaderContext leaf = leaves.get(subIndex);
    final BitSet bits = parents.getBitSet(leaf);
    return leaf.reader().document(bits.nextSetBit(childDocID - leaf.docBase));
  }

但我不确定如何做相反的事情。即如何获取所有的孩子给一个父文档。
如有任何建议,我们将不胜感激。

uinbv5nw

uinbv5nw1#

最后我使用了下面的代码。它看起来很有效:

private List<Integer> getChildDocIds(IndexSearcher indexSearcher, int parentDocId) throws IOException {
    //Use a query in QueryBitSetProducer constructor which identifies parent docs
    BitSetProducer parentsFilter = new QueryBitSetProducer(new TermQuery(new Term("child", "N")));
    IndexReader indexReader = indexSearcher.getIndexReader();
    List<LeafReaderContext> leaves = indexReader.leaves();
    int subIndex = ReaderUtil.subIndex(parentDocId, leaves);
    LeafReaderContext leaf = leaves.get(subIndex);
    int localParentDocId = parentDocId - leaf.docBase;
    List<Integer> childDocs = new ArrayList<>();
    if (localParentDocId == 0) { 
        //not a parent, or parent has no children
        return childDocs;
    }
    int prevParent = parentsFilter.getBitSet(leaf).prevSetBit(localParentDocId - 1);
    for(int childDocIndex = prevParent + 1; childDocIndex < localParentDocId; childDocIndex++) {
        childDocs.add(leaf.docBase + childDocIndex);
    }
    return childDocs;
}
u5i3ibmn

u5i3ibmn2#

根据你的回答我做了一个C#端口的函数,看起来也是可行的。
我只需要得到嵌套的文档没有任何过滤器或quires。

private List<Lucene.Net.Documents.Document> GetNestedDocuments(IndexSearcher searcher, int parentDocId)
{
    List<Lucene.Net.Documents.Document> documents = new List<Lucene.Net.Documents.Document>();

    int subIndex = ReaderUtil.SubIndex(parentDocId, searcher.IndexReader.Leaves);
    var leaf = searcher.IndexReader.Leaves[subIndex];

    if (parentDocId > leaf.DocBase)
    {
        for (var childDocIndex = leaf.DocBase; childDocIndex < parentDocId; childDocIndex++)
        {
            var childDoc = searcher.Doc(childDocIndex);
            documents.Add(childDoc);
        }
    }

    return documents;
}

相关问题