2014-02-26 79 views
4

我使用基於SolrJ的客戶端來查詢Solr,並且我一直試圖構建HTTP請求,其中排除了facet名稱/值對。我正在使用的Web界面有一個改進的進一步功能,允許排除一個或多個方面值。我有3個方面的領域:域名,內容類型和作者,我希望能夠通過排除他們每個人來處理faceting。例如,q = Dickensfq=-author:Dickens, Janet將構建以下HTTP請求:使用SolrJ過濾器查詢排除

/solr/solrbase/select?q=Dickens&fq=-author:Dickens%2c+Janet&wt=json&indent=true 

儘管XML轉儲將是這樣的:

   <facets> 
       <facet name="author"> 
       <facetEntry count="20">Dickens, Charles</facetEntry> 
       <facetEntry count="10">Dickens, Sarah</facetEntry> 
       </facet> 
      </facets> 

到目前爲止,Java實現,我有工作似乎並不處理篩選查詢排除:

private HttpSolrServer solrServer; 
solrServer = new HttpSolrServer("http://localhost:8983/solr/"); 

private static final String CONFIG_SOLR_FACET_FIELD = "facet_field"; 
private String[] _facetFields = new String[] {"author"}; 

private static final String CONFIG_SOLR_FACETS = "facets" 
    Element el = myParams.getChild(CONFIG_SOLR_FACETS); 

     _facetUse = el.getAttributeValue("useFacets", "true"); 
     _facetMinCount = el.getAttributeValue("minCount", String.valueOf(1)); 
     _facetLimit = el.getAttributeValue("limit", String.valueOf(20)); 


List vals = el.getChildren(CONFIG_SOLR_FACET_FIELD); 
     if (vals.size() > 0) { 
      _facetFields = new String[vals.size()]; 
      for (int i=0; i < vals.size(); i++) { 
      _facetFields[i] = ((Element)vals.get(i)).getTextTrim(); 
      } 
     } 

SolrQuery query = new SolrQuery(); 
query.setQuery(qs); 


List facetList = doc.getRootElement().getChildren("facet"); 
        Iterator<String> it = facetList.iterator(); 
        while (it.hasNext()) { 
         Element el = (Element)it.next(); // 
         String name = el.getAttributeValue("name"); 
         String value = el.getTextTrim(); 
         if (name != null && value != null) {  
          facets.add(name+":"+value); 
         } 

        } 


query.setQuery(qs). 
      setFacet(Boolean.parseBoolean(_facetUse)). 
      setFacetMinCount(Integer.parseInt(_facetMinCount)). 
      setFacetLimit(Integer.parseInt(_facetLimit)). 

     for (int i=0; i<_facetFields.length; i++) { 
      query.addFacetField(_facetFields[i]);  
     }; 

     for (int i=0; i<facets.size(); i++) { 
      query.addFilterQuery(facets.get(i)); 
     }; 
    return query; 

    } 

我建議沿着這些線路使用的東西:

SolrQuery solrQuery = new SolrQuery(); 
    solrQuery.set(CommonParams.FQ, 「-author:Dickens,Janet」); 

但是,這似乎是一種硬編碼方法,它不能輕易應用於所有3個方面和所有方面值。我看過this,但是我仍然不清楚應該如何在當前代碼中包含排除變體。你能幫忙嗎?

感謝的確,

編輯1

我重視的代碼來構建/準備Solr的查詢,但我應該還包括Solr的實際情況是怎麼樣查詢:

private QueryResponse execQuery(SolrQuery query) throws SolrServerException { 
    QueryResponse rsp = solrServer.query(query); 
    return rsp;  

} 

此外,發佈轉換Solr查詢的代碼會很有幫助響應的方面轉化爲可通過Web應用程序來理解:

Element elfacets = new Element("facets"); 
      List<FacetField> facets = rsp.getFacetFields(); 
      if (facets != null) { 
       int i = 0; 
       for (FacetField facet : facets) { 
        Element sfacet = new Element("facet"); 
        sfacet.setAttribute("name", facet.getName()); 

        List<Count> facetEntries = facet.getValues(); 

        for(FacetField.Count fcount : facetEntries) { 
         Element facetEntry = new Element("facetEntry"); 
         facetEntry.setText(fcount.getName()); 
         facetEntry.setAttribute("count", String.valueOf(fcount.getCount())); 
         sfacet.addContent(facetEntry); 
        } 
        elfacets.addContent(sfacet); 

      } 
      root.addContent(elfacets); 
     } 


     doc.addContent(root); 

     return doc; 
    } 

"facets"無非是XSLT,其中包含如何通過Web應用程序的處理,以Solr的面與面映射規則的更多。

編輯2 我附上"facets"模板,其通過該代碼被稱爲在EDIT 1提出:

<xsl:template name="facets"> 
       <xsl:param name="q" /> 
       <xsl:analyze-string select="$q" regex='AND facet_(.*?):\(("?.*?"?)\)'> 
         <xsl:matching-substring> 
         <xsl:choose> 
         <xsl:when test="regex-group(1) = 'author'"> 
            <facet name="author"><xsl:value-of select="regex-group(2)" /></facet> 
         </xsl:when>  
         </xsl:choose> 
         </xsl:matching-substring> 
         <xsl:non-matching-substring> 
         <!--<xsl:analyze-string select="$q" regex='AND NOT facet_(.*?):\(("?.*?"?)\)'> 
         <xsl:matching-substring> 
         <xsl:choose> 
         <xsl:when test="regex-group(1) = 'author'"> 
            <facet name="author"><xsl:value-of select="regex-group(2)" /></facet> 
         </xsl:when> 
         </xsl:choose> 
        </xsl:matching-substring> 
        </xsl:analyze-string>--> 
        </xsl:non-matching-substring> 
       </xsl:analyze-string> 
    </xsl:template> 
</xsl:stylesheet> 

該模板只採用了author面,但是我有總共3個方面。應該注意的是,我的Web應用程序具有以下用於排除構面的語法:

AND NOT facet_author:("Dickens, Janet") 
+1

你想在需要的基礎上排除'fq',對嗎?你能控制參數傳遞給查詢嗎? – buddy86

+0

是的,那正是我想要做的!你如何將參數傳遞給查詢?哪裏?你能提供例子嗎?請參閱我的附加編輯,其中顯示模板構面。感謝您的幫助。 – paranza

回答

2

我確定您在某種方法中有以下幾行。而不是硬編碼的fq部分,有一些變數。

SolrQuery solrQuery = new SolrQuery(); 
solrQuery.set(CommonParams.FQ, 「-author:Dickens,Janet」); 

如果您需要使用fq,請傳遞適當的參數(例如「-author:Dickens,Janet」)。否則傳遞一個空字符串。所以,你的查詢將會像

/solr/solrbase/select?q=Dickens&fq=&wt=json&indent=true 

然後添加你的faceting部分的查詢。雖然你的查詢有fq=,但它不會引發錯誤。它基本上不會爲fq部分工作。但其餘的查詢將正常工作。

希望這會有所幫助。

+0

對延遲迴復表示歉意,但我已離開。我不能像你的例子那樣傳遞一個合適的參數。你是否建議使用類似solrQuery.set(CommonParams.FQ)的東西?非常感謝! – paranza