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

SOLR exact match boost over text containing the exact match

我找不到更好的标题,如果可能的话,我希望稍后根据您的最终建议进行更改。

我的问题:

我有一个音乐艺术家的数据库。这些看起来像这样:"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" 结果还可以,但并不完美,看起来像这样:

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

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

如何实现? (过滤器、标记器、复制字段等都无关紧要。我无法更改 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 字段可能应该有一个映射到 fieldType 条目的 type 值。 fieldType应该有class="solr.TextField",不应该有omitNorms="true"。除非您在名称字段上明确省略规范,否则 Solr 会在计算文档分数时考虑名称与您的搜索词匹配的程度以及您的搜索词在名称中匹配的次数。 "dr. dre" 会获得最高分,因为名称中 100% 的词与您的搜索匹配。

您可以在 the Solr documentation wiki 上阅读规范并查看很好的通用文本 fieldType 配置,或者在您下载的特定 Solr 版本的 Solr 文档中。依赖规范的优势在于,除了相当容易实施之外,它们是渐进的。因此,虽然 "dr. dre" 是 相关的记录,其名称 100% 与您的搜索匹配,但 "eminem & dr. dre" 也将是 更多 比 "a whole list of guys & also dr. dre" 更相关,因为您的搜索字词在名称中所占比例更大。

精确匹配

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

如果您决定实施完全匹配搜索,那么您可能希望在 schema.xml:

中设置一个复制域
<copyField source="name" dest="exactName"/>

然后,您需要同时搜索这两个字段。如何执行此操作取决于您使用的查询解析器。如果您使用 standard/lucene query parser, then you will need to set up your queries with OR searching, (e.g. q=name:"dr. dre" OR exactName:"dr. dre"^4). A "^4" after a search term makes that match 4 times as important/relevant as a match elsewhere in the query. If you are using the Dismax or Extended Dismax query parser, you have access to the newer qf 字段,它允许您提供用于搜索的字段列表,并设置一些字段比其他字段更重要。例如 qf=exactName^4 name&q="dr. dre" 告诉 Solr 在两个字段中检查 "dr. dre",但认为 exactName 字段中的匹配是 name 字段中匹配的 4 倍相关。 (如果这对您有用,可以在 solrconfig.xml 中设置默认值 qf,这样就不需要在每次查询时都重新声明。)

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

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

但更有可能的是,您希望在 "exact" 中允许一些变化,在这种情况下,您将需要制作一个新的 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"/>

这个非常基本的示例仅包括关键字分词器以将整个名称保留为单个标记,以及小写过滤器以确保大小写之间的差异无关紧要。如果您希望完全匹配允许任何其他条件,则需要修改 fieldType 的分析。

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