如何根据lucene搜索结果查询lucene?

时间:2015-05-29 14:46:32

标签: java lucene

以下是我试图解决的问题:

  • 我有多个lucene索引,每个索引都包含相同数据结构的子集(它们具有相同的字段,但某些索引中的字段可能存在也可能不存在)
  • 索引之间共享一个全局标识符。这意味着,如果有4个索引,则最多可能有4个文档共享一个密钥。
  • 我有一个lucene查询

我使用MultiReader一起查询所有索引,并且我能够使用ReaderUtil找出命中来自哪个子索引。到目前为止一切顺利,但问题在于:

为了执行(相当复杂的)合并逻辑,我需要所有子指标中的文档以及与原始查询中至少一个文档匹配的任何键。

以下是一个例子:

索引1

1:{key: "foo", name: "Name A", something: 42}

2:{key: "bar", something: 2}

索引2

27:{key: "foo", something: 2}

索引3

102:{key: "foo", name: "Name B"}

103:{key: "bar", something: 999}

现在,如果我要对名称"Name A"执行查询,我只会从索引1获取文档1

我真正需要的是所有索引中包含该查询中所有键的所有文档,这些文档都是键foo的文档:

  • doc 1 from index 1
  • doc 27 from index 2
  • doc 102 from index 3

基于name: "Name A"的原始查询。

我可以在没有2个单独查询的情况下实现此目的,第二个是基于第一个检索到的密钥的大量OR吗?有更有效的方法吗?

1 个答案:

答案 0 :(得分:0)

好的,这是我如何让它发挥作用:

TermFirstPassGroupingCollector与群组字段id一起使用,并使用实际搜索查询执行搜索(例如name: Name A

TermFirstPassGroupingCollector firstPassCollector = new TermFirstPassGroupingCollector(
            "<grouping field name, e.g. id>",
            Sort.INDEXORDER,
            x);

searcher.search(query, firstPassCollector);

Collection<SearchGroup<String>> firstPassResult = firstPassCollector.getTopGroups(0, false)

然后,使用第二个传递收集器,并使用MatchAllDocsQuery收集所有组中的所有字段:

TermSecondPassGroupingCollector secondPassCollector = new TermSecondPassGroupingCollector(
            fieldNaming.getIdFieldName(),
            firstPassResult,
            Sort.INDEXORDER,
            Sort.INDEXORDER,
            maxDocsPerGroup,
            false,
            false,
            false);

searcher.search(new MatchAllDocsQuery(), secondPassCollector);

我现在可以遍历所有(匹配的)组,并获取每个组中的所有文档,无论它是否明确匹配:

for (GroupDocs groupDocs : documentGroups) {

    if (groupDocs.totalHits == 0) {
        continue;
    }

    for (int doc : groupDocs.scoreDocs) {

        Document document = reader.document(doc);
        ...
    }
}

问题解决了。确保你像处理getTopGroups()的第一个收集者null一样处理怪异。