2011-12-05 24 views
2

我有一個有趣的用例,我們有一個Solr實現,Solr架構中有一些字段在執行查詢時不應返回。理想的解決方案是更改調用程序,因此它不會像現在這樣查詢&fl=score,只會請求必要的字段,但這不會在短期內發生,因此同時我們必須過濾掉一些字段來自Solr的迴應。Solr在自定義搜索組件中使用SolrParams替代「fl」參數

我們認爲對性能影響最小的方法(讓我知道是否有更好的方法來做到這一點)是覆蓋&fl=參數,因此它列出了所有應該被濾除的字段。爲此,我們在RequestHandler組件列表中添加了一個新的SearchComponent,它修改&fl參數。我們用這種方法遇到的問題是,一旦我們從SolrQueryRequest得到SolrParams,它就不能被修改(我認爲這是正確的做法,因爲它可能會改變另一個SearchComponent依賴的東西)。但是我們仍然需要找到一種方法去除這些額外的領域。

所以,這是我們開始寫代碼:

public void prepare(ResponseBuilder rb) throws IOException { 
     SolrQueryRequest req = rb.req; 
     SolrParams params = req.getParams(); 
     String fl = params.get("fl"); 
     //Remove the "fl" parameter from params and replace it with a new list: 
     //Cannot be done" 
     ... 

跑進不能夠添加到SolrParams的問題。

作爲計劃B,相同的SearchComponent將刪除process()方法中的字段,但以這種方式執行操作會更慢。該代碼要經過所產生的SolrDocumentList,併爲每個SolrDocument通話removeFields(),類似於:(簡化代碼)

public void process(ResponseBuilder rb) throws IOException { 
    ... 
    SolrQueryResponse rsp = rb.rsp; 
    NamedList values = rsp.getValues(); 
    SolrDocumentList docs = (SolrDocumentList) values.get("response"); 
    Iterator<SolrDocument> docsIterator = sdoclist.iterator(); 
    while (docsIterator.hasNext()) { 
     SolrDocument sd = sdocIterator.next(); 
     sd.removeFields(field); 
     ... 

上的任何想法如何/如果可以做到這一點?

感謝您的任何建議!

+0

我想你應該創建自己的SearchParser的SearchComponent insteard。在那裏你可以改變'fl'參數。 – Matej

回答

1

使用您自己的SearchHandler,您可以在任何查詢參數中指定不變量(無論請求將始終固定的東西),其中包括flfl。

這件事情中的臺詞:

<requestHandler name="filtered" class="solr.StandardRequestHandler"> 
    <lst name="invariants"> 
     <str name="fl">score,id,something_else,etc.</bool> 
    </lst> 

    </requestHandler> 

更多的文檔: http://wiki.apache.org/solr/SearchHandler

唯一的問題是,現在,有沒有負面FL參數(即返回除了那些我」的所有領域告訴你)。 https://issues.apache.org/jira/browse/SOLR-3191

最後,指定要在查詢時使用的SearchHandler,只需添加& QT =過濾(或者你使用它的名字)

0

嘗試刪除字段,你不希望來自ReturnFields對象。 例如,像這樣:

@Override 
public void process(ResponseBuilder rb) throws IOException { 
    String fl = rb.req.getParams().get(CommonParams.FL); 
    List<String> fields = Lists.newArrayList(fl.split(",")); 
    List<String> newFields = Lists.newArrayList(); 
    for (String field : fields) { 
     if (!field.equals("score")) { 
      newFields.add(field); 
     } 
    } 
    String newFl = Joiner.on(",").join(newFields); 
    ReturnFields returnFields = new ReturnFields(newFl, rb.req); 
    rb.rsp.setReturnFields(returnFields); 
} 

我在solrconfig.xml中設定自定義SearchComponent在「最後的組件」。

P.S:我使用番石榴庫作爲Lists和Joiner。

相關問題