java - 使用 SolrJ 过滤查询排除

标签 java solr solrj faceted-search

我使用基于 SolrJ 的客户端来查询 Solr,并且我一直在尝试构建排除了构面名称/值对的 HTTP 请求。我正在使用的 Web 界面具有进一步改进的功能,允许排除一个或多个构面值。我有 3 个分面字段:域、内容类型和作者,我希望能够通过排除每个字段来处理分面。例如,q = Dickens AND fq=-author:Dickens, Janet 将构建以下 HTTP 请求:

/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,它包含有关如何将 Solr facets 与 web 应用程序处理的 facets 进行映射的规则。

编辑 2 我附加了 "facets" 模板,该模板由编辑 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")

最佳答案

我确定您在某些方法中有以下几行。不要对 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

然后添加查询的分面部分。虽然您的查询有 fq=,但它不会抛出错误。它基本上不适用于 fq 部分。但查询的其余部分将正常工作。

希望这会有所帮助。

关于java - 使用 SolrJ 过滤查询排除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22041067/

相关文章:

java - JPA 2.1 表示属性 "indexes is undefined"

text - 在 Solr 中搜索号码/产品代码

java - 一个简单的对称类,在 void main (String[] args) 中使用 args

java - 为什么我的 java 代码不能运行?

apache - 无法在 Amazon EC2 上安装 solr

python - Django Haystack - 无需搜索查询即可显示结果?

unit-testing - 如何使用 SolrJ 禁用 solr 日志记录?

java - 用Java将pdf文档添加到Solr

autocomplete - Solrj:如何指定路径

java - 将一定范围的数字添加到 Java 数组