首页 > 解决方案 > 在 solr 搜索结果中需要完全匹配

问题描述

目前,我在进行精确搜索(双引号内的查询)时面临以下小问题。

{
  "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
      },

上面的“销售”查询与索引数据中的“销售”术语匹配,这并不准确。这也是由于定义的文本字段中的 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 case 查询解析器来解决确切的搜索问题(在搜索网络之后)。基本上,如果用户输入查询有双引号,我想实现精确搜索。当用户使用 switch 查询解析器指定 exact=true 时,我想实现精确搜索。但我有点卡住了,因为我没有得到任何结果。有人可以帮忙吗?

PS 也附上模式定义。请检查。

<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>

标签: solrexact-match

解决方案


使用双引号并不意味着精确。它只允许您进行短语查询,其中术语必须彼此出现。Solr (Lucene) 搜索您生成的令牌。

使用具有不更改标记的特定定义的字段(即无 ngram、无词干等)。如果您只想完全匹配整个字段(但不区分大小写),请使用 aKeywordTokenizer和 a LowercaseFilter。如果您只想对整个字段进行区分大小写的精确匹配,请使用string字段。

如果您想要与每个术语完全匹配,请使用具有您所追求的行为的标记器,并选择过滤器以规范化大小写(即使其不区分大小写)。然后,您根据用户是否要求进行精确搜索来决定要查询的字段。

您将不得不确定"foo" bar应该如何表现以及应该如何"foo bar" baz表现。


推荐阅读