Lucene-如何在父文档中获取所有子文档';给定父文档ID的s块

Lucene-如何在父文档中获取所有子文档';给定父文档ID的s块,lucene,Lucene,我使用直接向上的Lucene(无Solr或ElasticSearch)为一组遵循父子层次结构的文档编制索引 我使用“块”来完成这一点,方法是将所有子项(后跟父项)添加到同一块调用中: writer.addDocuments(childrenAndParentDocList) 我正在对所有父级和子级进行自由文本搜索(在子级搜索中使用ToParentBlockJoinQuery链接到父级文档),这将返回一组很好的父级文档,这些文档要么与查询匹配,要么具有与查询匹配的子级 我需要做的下一件事是获取我

我使用直接向上的Lucene(无Solr或ElasticSearch)为一组遵循父子层次结构的文档编制索引

我使用“块”来完成这一点,方法是将所有子项(后跟父项)添加到同一块调用中:

writer.addDocuments(childrenAndParentDocList)
我正在对所有父级和子级进行自由文本搜索(在子级搜索中使用ToParentBlockJoinQuery链接到父级文档),这将返回一组很好的父级文档,这些文档要么与查询匹配,要么具有与查询匹配的子级

我需要做的下一件事是获取我拥有的所有父文档的所有子文档

我在lucene测试中看到了一个方法,它展示了如何在给定子文档的情况下获取父文档

  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));
  }
private Document getParentDoc(IndexReader reader、BitSetProducer parents、int childDocID)抛出IOException异常{
最终列表leaves=reader.leaves();
final int subIndex=ReaderUtil.subIndex(childDocID,leaves);
final leadercontext leaf=leaves.get(子索引);
最终位集位=parents.getBitSet(leaf);
返回leaf.reader().document(bits.nextSetBit(childDocID-leaf.docBase));
}
但我不确定如何做相反的事情。i、 e.如何获取给定父文档的所有子级


任何建议都将不胜感激。

我最终使用了下面的代码。这似乎是可行的:

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;
}
private List getChildDocId(IndexSearcher IndexSearcher,int parentDocId)引发IOException{
//在QueryBitSetProducer构造函数中使用一个查询来标识父文档
BitSetProducer parentsFilter=new QueryBitSetProducer(新术语查询(新术语(“子”,“N”)));
IndexReader IndexReader=indexSearcher.getIndexReader();
List leaves=indexReader.leaves();
int subIndex=ReaderUtil.subIndex(parentDocId,leaves);
LeaveReaderContext叶=leaves.get(子索引);
int localParentDocId=parentDocId-leaf.docBase;
List childDocs=new ArrayList();
如果(localParentDocId==0){
//不是父母,或者父母没有子女
返回childDocs;
}
int prevParent=parentsFilter.getBitSet(leaf.prevSetBit)(localParentDocId-1);
对于(int childDocIndex=prevParent+1;childDocIndex
根据您的回答,我制作了一个c#端口的函数,它似乎也能工作

我只需要获取嵌套文档,不需要任何过滤器或要求

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;
}
private List GetNestedDocuments(索引搜索器搜索器,int-parentDocId)
{
列表文档=新列表();
int subIndex=ReaderUtil.subIndex(parentDocId,searcher.IndexReader.Leaves);
var leaf=searcher.IndexReader.Leaves[subIndex];
if(parentDocId>leaf.DocBase)
{
for(var childDocIndex=leaf.DocBase;childDocIndex
您的问题是如何将所有子项放在一个父文档之前。这等于获取上一个父级。所以最有可能您正在寻找这个函数:org.apache.lucene.util.BitSet.preveSetBit(int)谢谢,非常好用。对于其他人:如果您没有可用的
QueryBitSetProducer
,可以使用
FixedBitSetCachingWrapperFilter
,然后使用
var bitSet=(FixedBitSet)parents.GetDocIdSet(leaf,null)
,其中parents是您的
FixedBitSetCachingWrapperFilter
。显然,存储缓存包装器并跨查询重用。