2011-12-12 65 views
0

另一個潛在的令人尷尬的問題。請隨時指出可能被忽略的任何明顯的解決方案 - 我之前已經搜索過解決方案,但什麼也沒找到,但有時候是選擇錯誤的關鍵字來搜索的問題。
以下是這種情況:幾個月前爲一個企業級系統編寫了我自己的RequestHandler,以便在對solr內核進行的所有查詢中插入一些必要的安全參數作爲額外的過濾器。一切都會平穩運行,直到從索引查詢得到的文檔被收集起來並返回給用戶的部分。Solr自定義RequestHandler - 優化結果

基本上,在創建過濾器並執行查詢後,我們得到一組文檔ID(和分數),但是爲了構建結果集,一次只打一個結果集,然後我們必須遍歷ID,這比查詢標準請求處理程序要慢10倍,並且隨着結果數量的增加而變得更糟。更糟糕的是,由於我們的模式很大程度上依賴動態字段的靈活性,因此除了測試每個文檔的所有可能組合之外,沒有辦法(我知道)先前檢索要檢索每個文檔的字段列表。

下面的代碼是生產中運行的代碼的簡化版本,用於查詢SolrIndexSearcher並構建響應。

事不宜遲,我的問題是:

  • 有檢索一次所有的結果,而不是由文件建立一個響應文件的方法嗎?
  • 是否有可能獲得每個結果的字段列表,而不是測試所有可能的組合?
  • 我應該知道的代碼中的任何特定的WTF?隨時踢我!
//function that queries index and handles results 
private void searchCore(SolrIndexSearcher searcher, Query query, 
     Filter filter, int num, SolrDocumentList results) { 

    //Executes the query 
    TopDocs col = searcher.search(query,filter, num); 

    //results 
    ScoreDoc[] docs = col.scoreDocs;   

    //iterate & build documents 
    for (ScoreDoc hit : docs) { 
     Document doc = reader.document(hit.doc); 
     SolrDocument sdoc = new SolrDocument(); 

     for(Object f : doc.getFields()) { 
      Field fd = ((Field) f); 

      //strings 
      if (fd.isStored() && (fd.stringValue() != null)) 
       sdoc.addField(fd.name(), fd.stringValue()); 
      else if(fd.isStored()) { 
       //Dynamic Longs 
       if (fd.name().matches(".*_l")) { 
        ByteBuffer a = ByteBuffer.wrap(fd.getBinaryValue(), 
          fd.getBinaryOffset(), fd.getBinaryLength()); 
        long testLong = a.getLong(0); 
        sdoc.addField(fd.name(), testLong); 
       } 
       //Dynamic Dates 
       else if(fd.name().matches(".*_dt")) { 
        ByteBuffer a = ByteBuffer.wrap(fd.getBinaryValue(), 
         fd.getBinaryOffset(), fd.getBinaryLength()); 
        Date dt = new Date(a.getLong()); 
        sdoc.addField(fd.name(), dt); 
       } 
       //... 
      }     
     } 
     results.add(sdoc); 
    } 
} 

+0

爲了說明起見,您創建了此自定義RequestHandler,僅用於向每個請求添加其他過濾器的唯一目的。那是對的嗎? – rfeak

+0

@rfeak - 簡短的回答,是的。它是相關的嗎?你會建議任何不同的方法? – 12N

+1

是的。如果我記得正確(已過去2年),可以在添加到每個查詢的XML文件中添加默認過濾器。然後,默認過濾器像其他任何過濾器一樣緩存在FilterCache中。它們與其他過濾器的聚合速度應該很快,並且您不必獲取文檔來應用過濾器。不知道你是否考慮過這種方法。 – rfeak

回答

0

每管理員的要求:

雖然這並沒有回答您的具體問題,我建議另一種選擇,以解決您的問題。

要向所有查詢添加過濾器,可以在SolrConfig.xml文件的StandardRequestHandler中添加「附加」部分。添加「fl」(代表過濾器)部分並添加您的過濾器。通過StandardRequestHandler傳送的每個請求都會自動附加過濾器。

此篩選器與其他任何對象一樣對待,所以它被緩存在FilterCache中。結果是在查詢時相當快地過濾(通過docIds)。這可以讓您避免必須拉取解決方案中的單個文檔來應用過濾標準。