另一個潛在的令人尷尬的問題。請隨時指出可能被忽略的任何明顯的解決方案 - 我之前已經搜索過解決方案,但什麼也沒找到,但有時候是選擇錯誤的關鍵字來搜索的問題。
以下是這種情況:幾個月前爲一個企業級系統編寫了我自己的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);
}
}
爲了說明起見,您創建了此自定義RequestHandler,僅用於向每個請求添加其他過濾器的唯一目的。那是對的嗎? – rfeak
@rfeak - 簡短的回答,是的。它是相關的嗎?你會建議任何不同的方法? – 12N
是的。如果我記得正確(已過去2年),可以在添加到每個查詢的XML文件中添加默認過濾器。然後,默認過濾器像其他任何過濾器一樣緩存在FilterCache中。它們與其他過濾器的聚合速度應該很快,並且您不必獲取文檔來應用過濾器。不知道你是否考慮過這種方法。 – rfeak