2015-05-29 105 views
0

這裏是我試圖解決的問題:如何根據lucene搜索結果查詢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所有文檔中的所有文件:從指數1

  • DOC 1
  • DOC 27指數2基於用於name: "Name A"原始查詢
  • 文檔102從索引3

我可以在沒有兩個單獨查詢的情況下實現這個功能,第二個是基於第一個檢索到的密鑰的大規模OR?有沒有更高效的方法?

回答

0

好吧,這裏就是我得到了它的工作:

使用同組字段id一個TermFirstPassGroupingCollector,並用實際的搜索查詢(例如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處理奇怪。