如何配置Solr对字段名称(而不是值)执行不区分大小写的搜索?

时间:2017-10-04 19:37:33

标签: search indexing solr lucene

在我的Solr核心中,我有一个如下定义的字段:

<field name="firstName" type="text_general" multiValued="false" indexed="true" stored="true"/>

我可以使用以下内容查询此字段:​​“firstName:nathan”。但是,我希望能够使用以下任何一个搜索此字段:

  • “姓:森”
  • “姓:森”
  • “FIRSTNAME:森”

是否可以将Solr配置为允许对字段名称进行不区分大小写的搜索?

请注意,我询问对字段的进行不区分大小写的搜索 - 这个问题已在StackOverflow上多次回答。

1 个答案:

答案 0 :(得分:4)

简短的回答是否定(从Solr的默认配置开始)

答案很长,但是你需要编写一些代码......

我想最好的选择是在你的应用程序中在索引和查询时间内遇到Solr之前更改它。 但是,如果索引在您的控制之下并且查询不在,并且您需要Solr仅在查询时间内处理此问题,则可以根据需要自定义查询解析器。为此,您需要:

1-写一个QParserPlugin:

package com.hoss.solr;

import org.apache.solr.common.params.SolrParams;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.search.LuceneQParserPlugin;
import org.apache.solr.search.QParser;

/**
 * @author alehoss
 */
public class MyQParserPlugin extends LuceneQParserPlugin {

    @Override
    public QParser createParser(String qstr, SolrParams localParams, SolrParams params, SolrQueryRequest req) {
        return new MyQParser(qstr, localParams, params, req);
    }

}

2-写一个QParser:

package com.hoss.solr;

import org.apache.lucene.search.Query;
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.search.LuceneQParser;
import org.apache.solr.search.SyntaxError;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author alehoss
 */
public class MyQParser extends LuceneQParser {

    private static final Logger log = LoggerFactory.getLogger(MyQParser.class);

    public MyQParser(String qstr, SolrParams localParams, SolrParams params, SolrQueryRequest req) {
        super(qstr, localParams, params, req);
    }

    @Override
    public Query parse() throws SyntaxError {
        String qstr = getString();
        if (qstr == null || qstr.length()==0) return null;
        log.warn("original query = " + qstr + "; querying for " + qstr.toLowerCase());
        setString(qstr.toLowerCase());
        return super.parse();
    }

}

3-将其导出到JAR并将其添加到solr contrib / custom目录(您可以使用其他名称创建它);

4-在solrconfig.xml中引用它:

<lib dir="${solr.install.dir:../../../..}/contrib/custom" regex=".*\.jar" />

5-更改要自定义的处理程序的查询解析器(例如/ select)。这里重要的是 defType 参数,该参数引用 myparser

<requestHandler name="/select" class="solr.SearchHandler">
    <!-- default values for query parameters can be specified, these
         will be overridden by parameters in the request
      -->
    <lst name="defaults">
      <str name="echoParams">explicit</str>
      <str name="defType">myparser</str>
      <int name="rows">10</int>
      <!-- <str name="df">text</str> -->
    </lst>
.
.
.
</requestHandler>

6 - 取消注释或声明您的queryParser:

<queryParser name="myparser" class="com.hoss.solr.MyQParserPlugin"/>

在这个匆忙的例子中,我没有考虑只降低字段名称。因此,它会小写整个查询(&#39; q&#39;参数),包括值,但如果这是一个问题(如果您确实有一个令牌不在的字段&t; lowercased),你可以改变实现并解析查询字符串以满足你的需求。

另一件事是,考虑到这个例子,您需要以小写形式声明所有字段名称,而不是像您的示例那样使用驼峰字符。用户输入的方式并不重要,查询将始终使用小写字段名称完成,因此字段名称必须以此形式存在于您的模式中。

有了这个,您就可以搜索以下任何一个:

  • &#34;姓:森&#34;
  • &#34;姓:森&#34;
  • &#34;姓:森&#34;

查询将始终使用&#34; firstname:nathan&#34;执行。因此,架构中字段的定义必须为 name =&#34; firstname&#34;

下行:您无法搜索使用大写字母编制索引的字段名称或动态字段名称,但如果您控制索引编制,则不会出现问题。

我的示例建立在LuceneParser(Solr的默认解析器)之上,但您可以选择另一个或创建一个全新的。以下是一些有用的文档:

关于解析的Oficial Solr doc:https://lucene.apache.org/solr/guide/6_6/query-syntax-and-parsing.html

完整示例的好文章与此处发布的文章类似:https://medium.com/@wkaichan/custom-query-parser-in-apache-solr-4634504bc5da