【问题标题】:How can I query lucene based on a lucene search result?如何根据 lucene 搜索结果查询 lucene?
【发布时间】:2015-05-29 14:46:32
【问题描述】:

这是我要解决的问题:

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

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

为了执行(相当复杂的)合并逻辑,我需要来自 all 子索引的文档,其中包含与原始查询中的至少一个文档匹配的任何键。

这是一个例子:

索引 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 的文档:

  • 索引 1 中的文档 1
  • 索引 2 中的 doc 27
  • 索引 3 中的 doc 102

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

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

【问题讨论】:

    标签: java lucene


    【解决方案1】:

    好的,这就是我的工作方式:

    使用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)
    

    然后,使用第二个 pass 收集器,并使用 MatchAllDocsQuery 收集所有组内的 all 字段:

    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。

    【讨论】:

      猜你喜欢
      • 2011-03-22
      • 2021-04-01
      • 1970-01-01
      • 2019-05-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多