在solr搜索结果中需要完全匹配

时间:2020-01-17 17:13:45

标签: solr exact-match

当前,我在进行精确搜索(双引号中包含的查询)时遇到以下小问题。

{
  "responseHeader": {
    "status": 0,
    "QTime": 1,
    "params": {
      "q": "\"sale\"",
      "indent": "true",
      "fl": "displayValue, categoryName, approved, averageRating, lastOneWeekCount, connectorName, score",
      "wt": "json",
      "_": "1579279511471"
    }
  },
  "response": {
    "numFound": 918,
    "start": 0,
    "maxScore": 11.044312,
    "docs": [
      {
        "displayValue": "Net Sales  Vs Contribution Margin",
        "categoryName": "Sales Analytics (B07)",
        "connectorName": "New BOBJ",
        "lastOneWeekCount": 3,
        "approved": "yes",
        "averageRating": 4,
        "score": 11.044312
      },

上面的“ sale”查询与索引数据中的“ Sales”字词匹配,这是不准确的。也由于在定义的文本字段(使用空白令牌生成器)中的EdgeNgramFilterFactory而发生这种情况。 我已经设法通过选择请求处理程序的当前实现逐步解决了不同的搜索问题,现在我需要解决上述完全匹配的问题。以下是我的solrconfig详细信息。

    <lst name="defaults">
      <str name="exact">false</str>
      <str name="echoParams">explicit</str>
      <int name="rows">10</int>
      <str name="defType">edismax</str>
      <str name="qf">
         displayValue^20 description^5 connectorName_txt zenDescription_txt^5 zenBusinessOwner_txt^2 
         categoryName^8 reportOwner^2 reportDetailsNameColumn^5 
      </str>
      <str name="pf2">
         displayValue^20 description^5 connectorName_txt zenDescription_txt^5 zenBusinessOwner_txt^2 
         categoryName^8 reportOwner^2 reportDetailsNameColumn^5 
      </str>
      <str name="pf3">
         displayValue^20 description^5 connectorName_txt zenDescription_txt^5 zenBusinessOwner_txt^2 
         categoryName^8 reportOwner^2 reportDetailsNameColumn^5 
      </str>
      <str name="tie">1</str>
      <str name="mm">100%</str>
      <int name="ps2">3</int>
      <int name="ps3">9</int>
      <int name="qs">0</int>
      <str name="df">text</str>
      <str name="q.alt">*:*</str>
      <str name="sort">score desc, averageRating desc, lastOneWeekCount desc</str>
      <str name="bq">
        query({!boost b=20}approved:"yes")
      </str>
    </lst>
    <lst name="appends">
      <str name="fq">{!switch case.false='*:*' case.true='text_ex:$q' v=$exact}</str>
    </lst>
  </requestHandler>

在上面的配置详细信息中,我试图通过在配置中添加一个额外的开关案例查询解析器(在搜索网络之后)来解决确切的搜索问题。基本上,如果用户输入查询具有双引号,我想实现精确搜索。当用户使用switch查询解析器指定确切= true时,我想实现精确搜索。但是我有点卡住,因为我没有得到任何结果。 有人可以帮忙吗?

P.S还要附加模式定义。请检查。

<fieldType name="text_ws" class="solr.TextField" omitNorms="false">
        <analyzer type="index" omitTermFreqAndPositions="false">  
            <charFilter class="solr.MappingCharFilterFactory" mapping="mapping-FoldToASCII.txt"/>
            <tokenizer class="solr.WhitespaceTokenizerFactory"/>
            <filter class="solr.LowerCaseFilterFactory" />    
            <filter class="solr.EdgeNGramFilterFactory" minGramSize="1" maxGramSize="15"/>
            <filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
        </analyzer> 
        <analyzer type="query"> 
            <charFilter class="solr.MappingCharFilterFactory" mapping="mapping-FoldToASCII.txt"/>
            <tokenizer class="solr.WhitespaceTokenizerFactory"/>
            <filter class="solr.LowerCaseFilterFactory" /> 
        </analyzer> 
    </fieldType>


    <fieldType name="text_exact" class="solr.TextField" omitNorms="false">
        <analyzer type="index" omitTermFreqAndPositions="false">  
            <charFilter class="solr.MappingCharFilterFactory" mapping="mapping-FoldToASCII.txt"/>
            <tokenizer class="solr.KeywordTokenizerFactory"/>
            <filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="0" 
            catenateWords="0" catenateNumbers="0" preserveOriginal="1" catenateAll="0" splitOnCaseChange="0"/>
            <filter class="solr.LowerCaseFilterFactory" />    
            <filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
        </analyzer> 
        <analyzer type="query"> 
            <charFilter class="solr.MappingCharFilterFactory" mapping="mapping-FoldToASCII.txt"/>
            <tokenizer class="solr.KeywordTokenizerFactory"/>
            <filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="0" 
            catenateWords="0" catenateNumbers="0" preserveOriginal="1" catenateAll="0" splitOnCaseChange="0"/>
            <filter class="solr.LowerCaseFilterFactory" />
        </analyzer> 
    </fieldType>

1 个答案:

答案 0 :(得分:1)

使用双引号并不表示确切。它仅允许您在短语必须彼此出现的地方进行词组查询。 Solr(Lucene)搜索您生成的令牌

使用具有特定定义的字段,该字段不会更改令牌(即,没有ngram,没有词干等)。如果只想完全匹配整个字段(但不区分大小写),请使用KeywordTokenizerLowercaseFilter。如果您只想对整个字段区分大小写且精确匹配,请使用string字段。

如果您希望与每个术语完全匹配,请使用带有您要遵循的行为的分词器,并选择过滤器以区分大小写(即使其不区分大小写)。然后,您可以根据用户是否要求精确搜索来决定要查询哪个字段。

您将不得不确定"foo" bar的行为方式以及"foo bar" baz的行为方式。