SOLR 精确匹配提升包含精确匹配的文本

标签 solr exact-match solr-boost

我找不到更好的标题,如果可能的话,我希望稍后在您最终建议时更改它。

我的问题:

我有一个音乐艺术家的数据库。这些看起来像这样:“dr. dre feat. akon”、“eminem & dr. dre”、“dr. dre feat.ll cool j”、“dr. dre”、“dr. dre feat. eminem & skylar grey” .我们只有两个字段:id 和 name。

在默认模式 solr 核心上,我运行此查询:“q=dr.dre”,结果正常但不完美,如下所示:

  • 博士。壮举。阿肯
  • 阿姆和博士dre
  • 博士。壮举。我很酷 j
  • 博士。 dre
  • ...

  • 请注意,他们得到了完全相同的分数。

    我想要的是将“dr. dre”作为第一个结果,然后是所有其他结果,如下所示:
  • 博士。 dre <<--博士dre 是第一
  • 阿姆和博士dre
  • 博士。壮举。我很酷 j
  • 博士。壮举。阿肯
  • ...

  • 我如何实现这一目标? (过滤器,标记器,复制字段等并不重要。正如我在其他论坛上看到的那样,我无法更改 solr 中的代码)

    谢谢。

    最佳答案

    有几种不同的方法可以让“dr. dre”结果首先出现。对于冗长的答案,我深表歉意,但正如 Solr 中经常发生的那样,答案取决于您的优先级和需求。

    This is probably redundant, but I'd like to start by making sure that you are seeing the scores for each result. Your question didn't make this entirely clear. When you make your query, you need to explicitly tell Solr to sort the results in descending order by their scores, though this can be set up in the solrconfig.xml. I imagine that you are already doing this, but just to make sure, you can try a query like this: q="dr. dre"&fl=*,score&sort=score desc. That will show you the calculated score for each result, and sort the results with the highest scores first.



    规范

    规范是一个灵活的选项,可以很自然地与 Solr 配合使用。您的 name字段可能应该有 type映射到 fieldType 的值入口。 fieldType应该有 class="solr.TextField" , 它不应该有 omitNorms="true" .除非您在名称字段中明确省略规范,否则 Solr 将在计算文档分数时考虑名称与您的搜索词匹配的程度以及您的搜索词在名称中匹配的次数。 “dr. dre”将获得最高分,因为名称中的单词 100% 与您的搜索匹配。

    您可以阅读有关规范的内容并查看很好的通用文本 fieldType the Solr documentation wiki 上的配置,或在您为您的特定 Solr 版本下载的 Solr 文档中。依赖规范的优势在于,除了相当容易实现之外,它们还具有渐进性。因此,虽然“dr. dre”将是最相关的记录,其姓名 100% 与您的搜索匹配,但“eminem & dr. dre”也将比“整个男士列表和 dr. dre”更相关,因为您的搜索词在名称中所占的比例较大。

    完全符合

    精确匹配在 Solr 中是一个复杂的问题,主要是因为存在不同程度的“精确性”,在现实生活中很少需要真正精确的匹配。例如,如果您的记录名为“dr. dre”,那么“dr dre”(不带句点)是否足够准确?是“Dr. Dre”吗?是“dre 博士”吗?

    如果您决定实现完全匹配搜索,那么您可能希望在 schema.xml 中设置一个复制字段。 :

    <copyField source="name" dest="exactName"/>
    

    然后,您需要一起搜索这两个字段。您如何执行此操作取决于您使用的查询解析器。如果您使用的是 standard/lucene查询解析器,那么您需要使用 OR 搜索来设置您的查询(例如 q=name:"dr. dre" OR exactName:"dr. dre"^4 )。搜索词后的“^4”使该匹配的重要性/相关性是查询中其他地方的匹配的 4 倍。如果您使用的是 DismaxExtended Dismax查询解析器,您可以访问更新的 qf 字段,它允许您提供用于搜索的字段列表,并将某些字段设置为比其他字段更重要。例如 qf=exactName^4 name&q="dr. dre"告诉 Solr 检查两个字段中的“dr. dre”,但考虑到精确名称字段中的匹配是名称字段中匹配项的 4 倍。 (如果这对您有用,默认 qf 可以设置在 solrconfig.xml 中,因此不需要在每次查询时都重新声明。)

    这留下了 fieldType未确定的确切名称字段。如果您觉得只有完全精确的匹配才有效,并且大小写或标点符号的变化使匹配不精确,那么您可以将精确名称字段设置为字符串:

    <field name="exactName" type="string" indexed="true" stored="false" multiValued="false"/>
    

    但更有可能的是,您会希望允许在什么算作“精确”方面有一些变化,在这种情况下,您需要创建一个新的 fieldType。 ,可能使用 Keyword Tokenizer ,这不会将确切名称分解为多个索引标记,而是将其保留为单个标记。例如:

    <fieldType name="exactish" class="solr.TextField">
      <analyzer>
       <tokenizer class="solr.KeywordTokenizerFactory"/>
       <filter class="solr.LowerCaseFilterFactory"/>
      </analyzer> 
    </fieldType>
    
    <field name="exactName" type="exactish" indexed="true" stored="false" multiValued="false"/>
    

    这个非常基本的例子只包括 Keyword Tokenizer 以将整个名称保留为单个标记,以及 Lower Case Filter 以确保大写和小写之间的差异不相关。如果您希望完全匹配可以容忍任何其他条件,则需要修改 fieldType 的分析。

    重要提示:在搜索字符串字段或具有 Keyword Tokenizer 的文本字段时,最好确保您发送到 Solr 的搜索始终带有引号(即短语搜索)。否则,在与该字段进行比较之前,您的搜索将被分解为单个术语,并且您的任何一个术语都不可能与整个索引字段匹配。这可能导致根本无法在字段中找到任何匹配项,除非值不包含空格。如果您只是使用规范来控制具有更标准标记化的 textField 中的相关性,这不是问题。

    关于SOLR 精确匹配提升包含精确匹配的文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29103155/

    相关文章:

    java - solr中的串联字符串搜索

    mysql - 如何在 Solr 搜索中获取精确的列

    python - Apache Solr 如何与 Django 1.5 配合使用?

    java - Solr 多个 boost 查询

    elasticsearch - 具有多个值的字段中的Elasticsearch Boost查询

    function - solr:使用函数创建过滤器查询

    PowerShell:查找确切的文件夹名称

    MySQL Replace() 无法替换 EXACT MATCH

    mysql - 区分大小写的数据库查询

    Elasticsearch 通过函数分数提升每个字段