SOLR完全匹配提升包含完全匹配的文本

Bog*_*anM 18 solr exact-match solr-boost

我找不到一个更好的标题,我希望稍后如果可能的话在你的最终消遣中改变它.

我的问题:

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

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

  • 博士.dre feat.阿肯
  • 埃米纳姆博士 DRE
  • 博士.dre feat.冷静的
  • 博士.DRE
  • ...

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

我想要的是将"dr.dre"作为第一个结果,然后是所有其他结果,如下所示:

  • 博士.dre << - 博士.dre是第一位的
  • 埃米纳姆博士 DRE
  • 博士.dre feat.冷静的
  • 博士.dre feat.阿肯
  • ...

我该如何实现这一目标?(过滤器,标记器,复制字段等等并不重要.我无法更改solr中的代码,因为我在其他论坛上看到过建议)

谢谢.

fra*_*ces 41

有几种不同的方法可以让"dr.dre"结果首先出现.我为冗长的答案道歉,但正如Solr经常发生的那样,答案取决于您的优先事项和需求.

这可能是多余的,但我想首先确保您看到每个结果的分数.你的问题并没有完全清楚.当您进行查询时,您需要明确告诉Solr按结果降序排序结果,尽管可以在中设置solrconfig.xml.我想你已经这样做了,但为了确保,你可以尝试这样的查询:q="dr. dre"&fl=*,score&sort=score desc.这将显示每个结果的计算得分,并首先对结果进行排序.

规范

规范是一种灵活的选择,可以很自然地与Solr一起使用.您的name字段应该具有type映射到fieldType条目的值.在fieldType大概应该有class="solr.TextField",它不应该有omitNorms="true".除非您在名称字段中明确省略规范,否则Solr会在计算文档分数时考虑名称中您的搜索字词的多少以及搜索字词与名称匹配的次数."dr.dre"得分最高,因为名称中100%的单词与您的搜索匹配.

您可以阅读有关规范的信息,并在Solr文档维基fieldType上查看一个很好的通用文本配置,或者在您下载的Solr文档中查看特定Solr版本.依赖规范的优点是,除了相当容易实现之外,它们是渐进的.因此,虽然"dr.dre"将是相关的记录,其100%的名称与您的搜索相匹配,"eminem&dr.dre"也将比"一整套人员和dr.dre" 更具相关性,因为您的搜索词是名称的较大比例.

完全符合

完全匹配在Solr中是一个复杂的问题,主要是因为存在不同程度的"精确度",并且在现实生活中很少需要真正完全匹配.例如,如果您的记录名称为"dr.dre",那么"dr dre"(没有句点)是否足够接近准确?是"Dr. Dre"吗?是"dr.dre"吗?

如果您决定实施完全匹配搜索,那么您可能需要在以下位置设置一个copyfield schema.xml:

<copyField source="name" dest="exactName"/>
Run Code Online (Sandbox Code Playgroud)

然后,您将希望一起搜索这两个字段.如何执行此操作取决于您使用的查询解析器.如果您使用标准/ 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",但是将exactName字段中的匹配视为与name字段中的匹配相关的4倍.(如果这适用于您,则qf可以设置默认值,solrconfig.xml因此不需要对每个查询进行重新设置.)

这使得fieldTypeexactName字段未定.如果您认为只有完全精确的匹配才有效,并且大小写或标点符号的变化会使匹配不准确,那么您可以将exactName字段设置为字符串:

<field name="exactName" type="string" indexed="true" stored="false" multiValued="false"/>
Run Code Online (Sandbox Code Playgroud)

但更有可能的是,你会想要允许一些变化为"精确",在这种情况下你需要创建一个新的fieldType,可能使用关键字标记,它不会将确切的名称分成多个索引标记,但保持它作为一个单一的标记.例如:

<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"/>
Run Code Online (Sandbox Code Playgroud)

这个非常基本的示例仅包括将整个名称保留为单个标记的关键字标记生成器,以及用于确保大写和小写之间的差异不相关的小写过滤器.如果您希望您的完全匹配能够容忍任何其他条件,则需要修改fieldType的分析.

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