添加计分概要文件以提高搜索分数

本文介绍如何根据条件为提高搜索分数定义计分概要文件。

条件可以是加权字段,例如,当在“标签”字段中找到的匹配项比在“描述”中找到的匹配项更相关时。 条件也可以是一个函数,如 distance 函数,它偏向当前位置指定距离内的结果。

计分概要文件在搜索索引中定义,并对查询请求调用。 可以创建多个概要文件,然后修改查询逻辑以选择使用哪一个。 计分概要文件嵌入索引定义中,包含用于提升匹配项分数的属性,其中概要文件中的附加条件提供了提升逻辑。 例如,你可能想要根据创收能力提升匹配项、提升新项或提升库存时间太长的项。

计分概要文件定义

计分概要文件是在索引架构中定义的命名对象。 概要文件可以由加权字段、函数和参数组成。

以下定义展示了名为“geo”的简单概要文件。 此示例用于提升在“hotelName”字段中具有搜索词的结果。 它还使用 distance 函数优先提升在当前位置 10 公里范围内的结果。 如果有人搜索“inn”一词,而“inn”恰好是酒店名称的一部分,包含当前位置 10 公里范围内带有“inn”的酒店的文档会在搜索结果中的较高位置出现。

"scoringProfiles": [
  {  
    "name":"geo",
    "text": {  
      "weights": {  
        "hotelName": 5
      }                              
    },
    "functions": [
      {  
        "type": "distance",
        "boost": 5,
        "fieldName": "location",
        "interpolation": "logarithmic",
        "distance": {
          "referencePointParameter": "currentLocation",
          "boostingDistance": 10
        }                        
      }                                      
    ]                     
  }            
]

若要使用此计分概要文件,请制定查询,以在请求中指定 scoringProfile 参数。 如果使用 REST API,则通过 GET 和 POST 请求指定查询。 在以下示例中,“currentLocation”具有单连接号 (-) 分隔符。 它后跟经度和纬度坐标,其中经度为负值。

GET /indexes/hotels/docs?search+inn&scoringProfile=geo&scoringParameter=currentLocation--122.123,44.77233&api-version=2020-06-30

请注意使用 POST 时的语法差异。 在 POST 中,“scoringParameters”是复数形式,并且是一个数组。

POST /indexes/hotels/docs&api-version=2020-06-30
{
    "search": "inn",
    "scoringProfile": "geo",
    "scoringParameters": ["currentLocation--122.123,44.77233"]
}

此查询对“inn”一词进行搜索,并在当前位置中传递。 请注意,此查询包含其他参数(例如 scoringParameter)。 查询参数(包括“scoringParameter”)在搜索文档 (REST API) 中介绍。

请参阅扩展示例以查看计分概要文件的更详细示例。

如何计算评分

系统会对全文搜索查询计算分数,以便对最相关的匹配项进行排名,并在响应顶部返回这些匹配项。 每个文档的总体分数是每个字段单项得分的汇总,其中每个字段的单项得分是根据该字段中搜索字词的字词频率和文档频率计算的(称为术语频率 - 逆向文档频率)。

可以使用 featuresMode(预览版)参数请求包含搜索结果的额外评分详细信息(包括字段级分数)。

何时添加评分逻辑

当默认排名行为不足以满足业务目标时,应创建一个或更多计分概要文件。 例如,可能会决定搜索相关性应更倾向于新添加的项。 同样,可能有一个包含利润率的字段,或其他某些指示营收潜力的字段。 提升对用户或业务更有意义的结果通常是采用计分概要文件的决定性因素。

搜索页面中基于相关度的排序也通过计分概要文件实现。 请考虑过去使用的可以按价格、日期、评分或相关度排序的搜索结果页。 在 Azure 认知搜索中,计分概要文件可以用于驱动“相关度”选项。 相关性定义由用户定义,取决于业务目标和你希望提供的搜索体验类型。

添加计分概要文件的步骤

要实现自定义计分行为,请将计分概要文件添加到定义该索引的架构。 在一个索引中可以具有最多 100 个计分概要文件(请参阅服务限制),但在任何给定查询中,一次只能指定一个概要文件。

  1. 从索引定义开始。 可以在现有索引上添加和更新计分概要文件,而无需重新生成它。 使用更新索引请求发布修订版本。

  2. 粘贴到本文中提供的模板中。

  3. 提供一个名称。 计分概要文件为可选项,但如果要添加一个概要文件,必须提供名称。 请务必遵循字段的认知搜索命名约定(以字母开头,避免使用特殊字符和保留字)。

  4. 指定提升条件。 单个概要文件可以包含加权字段函数或者两者都包含。

应该以迭代的方式工作,使用有助于证明或反驳给定概要文件有效性的数据集。

可以在 Azure 门户中定义计分概要文件(如以下屏幕截图所示),也可以通过 REST API 或 Azure SDK(例如用于 .NET 的 Azure SDK 中的 ScoringProfile 类)以编程方式定义计分概要文件。

Add scoring profiles page

使用加权字段

当字段上下文非常重要且查询是全文搜索时,请使用加权字段。 例如,如果查询包含字词“airport”,则你可能希望“Description”字段中的“airport”具有比 HotelName 中更多的权重。

加权字段由可搜索字段和用作乘数的正数组成。 如果 HotelName 的原始字段分数为 3,该字段的提升分数将变为 6,从而提升父文档本身的总体分数。

"scoringProfiles": [  
    {  
      "name": "boostKeywords",  
      "text": {  
        "weights": {  
          "HotelName": 2,  
          "Description": 5 
        }  
      }  
    }
]

使用函数

当简单的相对权重不足或不适用时,请使用函数,例如距离和新鲜度的情况(即对数值数据的计算)。 可以为每个计分概要文件指定多个函数。 有关认知搜索中使用的 EDM 数据类型的详细信息,请参阅支持的数据类型

函数 说明
“freshness” 按照日期/时间字段 (Edm.DateTimeOffset) 中的值进行提升。 此函数有一个“boostingDuration”属性,以便你可以指定一个表示发生提升的时间跨度的值。
“magnitude” 根据数值的高低程度进行提升。 调用此函数的方案包括按照利润率、最高价格、最低价格或下载次数提升。 此函数仅可与 Edm.DoubleEdm.Int 字段结合使用。 对于 magnitude 函数,如果想要反转模式(例如,将价格较低项提升至价格较高项之上),可以将范围反转为从高到低。 假设价格范围从 $100 到 $1,则将“boostingRangeStart”设置为 100,并将“boostingRangeEnd”设置为 1 以提升价格较低的项。
“distance” 按照邻近程度或地理位置进行提升。 此函数仅可与 Edm.GeographyPoint 字段结合使用。
“tag” 按照搜索文档和查询字符串通用的标记进行提升。 “tagsParameter”中提供了标记。 此函数仅可与类型为 Edm.StringCollection(Edm.String) 的搜索字段结合使用。

使用函数的规则

  • 函数只能应用于属性为可筛选的字段。
  • 函数类型(“freshness”、“magnitude”、“distance”、“tag”)必须为小写。
  • 函数不能包含 null 值或空值。

模板

本部分演示计分概要文件的语法和模板。 有关计分概要文件的属性,请参阅下一部分中的属性参考

"scoringProfiles": [  
  {   
    "name": "name of scoring profile",   
    "text": (optional, only applies to searchable fields) {   
      "weights": {   
        "searchable_field_name": relative_weight_value (positive #'s),   
        ...   
      }   
    },   
    "functions": (optional) [  
      {   
        "type": "magnitude | freshness | distance | tag",   
        "boost": # (positive number used as multiplier for raw score != 1),   
        "fieldName": "(...)",   
        "interpolation": "constant | linear (default) | quadratic | logarithmic",   

        "magnitude": {
          "boostingRangeStart": #,   
          "boostingRangeEnd": #,   
          "constantBoostBeyondRange": true | false (default)
        }  

        // ( - or -)  

        "freshness": {
          "boostingDuration": "..." (value representing timespan over which boosting occurs)   
        }  

        // ( - or -)  

        "distance": {
          "referencePointParameter": "...", (parameter to be passed in queries to use as reference location)   
          "boostingDistance": # (the distance in kilometers from the reference location where the boosting range ends)   
        }   

        // ( - or -)  

        "tag": {
          "tagsParameter":  "..."(parameter to be passed in queries to specify a list of tags to compare against target field)   
        }
      }
    ],   
    "functionAggregation": (optional, applies only when functions are specified) "sum (default) | average | minimum | maximum | firstMatching"   
  }   
],   
"defaultScoringProfile": (optional) "...", 

属性参考

属性 描述
name 必需。 这是计分概要文件的名称。 它遵循与字段相同的命名约定。 它必须以字母开头,不能包含点、冒号或 @ 符号,并且不能以短语 azureSearch(区分大小写)开头。
text 包含 weights 属性。
weights 可选。 指定可搜索字段和正整数或浮点数的名称/值对,用于提升字段的分数。 正整数或数字成为排名算法生成的原始字段分数的乘数。 例如,如果字段分数为 2,权重值为 3,则该字段的提升分数将为 6。 然后,汇总单个字段的分数来创建文档字段分数,并用该分数对结果集内的文档进行排名。
functions 可选。 计分函数仅可应用于可筛选的字段。
functions > type 计分函数的必需项。 指示要使用的函数类型。 有效值包括 magnitude、freshness、distance 和 tag。 可以在每个计分概要文件中包含多个函数。 函数名称必须小写。
functions > boost 计分函数的必需项。 用作原始分数乘数的正数。 它不能等于 1。
functions > fieldname 计分函数的必需项。 计分函数仅可应用于作为索引字段集合一部分且可筛选的字段。 此外,每个函数类型都引入了其他限制(freshness 与 datetime 字段结合使用、magnitude 与 integer 或 double 字段结合使用、distance 与 location 字段结合使用。)。 仅可按函数定义指定单个字段。 例如,若要在同一概要文件中使用两次 magnitude,则需要包含两个定义 magnitude,每个字段一个。
functions > interpolation 计分函数的必需项。 定义从范围起始至范围结束的分数提升增量的斜率。 有效值包括 Linear(默认值)、Constant、Quadratic 和 Logarithmic。 请参阅设置插值获取详细信息。
functions > magnitude magnitude 计分函数用于改变基于数值字段的值范围的排名。 一些最常见的用法示例如下:

“星级评分”:改变基于“Star Rating”字段内的值的计分。 如果两个项相关,具有较高评分的项先显示。
“利润”:当两个文档相关时,零售商可能希望先提升具有较高利润的文档。
“点击次数”:对于跟踪产品或页面点击行为的应用程序,可使用 magnitude 提升容易获得最多流量的项。
“下载次数”:对于跟踪下载量的应用程序,magnitude 函数可提升下载次数最多的项。
functions > magnitude > boostingRangeStart 设置对其进行量值计分的范围的起始值。 该值必须是整数或浮点数。 对于星级评分 1 到 4,这里应为 1。 对于超过 50% 的利润率,这里应为 50。
functions > magnitude > boostingRangeEnd 设置对其进行量值计分的范围的结束值。 该值必须是整数或浮点数。 对于星级评分 1 到 4,这里应为 4。
functions > magnitude > constantBoostBeyondRange 有效值为 true 或 false(默认)。 设置为 true 时,完整的提升将继续应用到有一个目标字段值高于范围上限的文档。 如果设置为 false,此函数的提升不会应用到有一个目标字段值超出范围的文档。
functions > freshness freshness 计分函数用于改变基于 DateTimeOffset 字段值的项的排名分数。 例如,具有较新日期的项可以排在日期较旧的项之上。

也可以排列日历事件等具有未来日期的项,以便接近当前日期的项可以排在距离当前日期较远的将来的项之上。

在当前服务版本中,范围的一端将固定为当前时间。 另一端是基于 boostingDuration 的过去的时间。 要提升将来的时间范围,请使用负的 boostingDuration。

提升从最大范围和最小范围改变的比率由应用到计分概要文件的内插确定(请见下图)。 若要反转应用的提升系数,请选择不超过 1 的提升系数。
functions > freshness > boostingDuration 设置一个有效期,超过这个有效期之后,针对特定文档的 Boosting 将停止。 请参阅以下语法和示例部分中的设置 boostingDuration
functions > distance 距离计分函数用于影响基于其相对的参考地理位置远近程度的文档分数。 参考位置在参数中指定为查询的一部分(使用 scoringParameter 查询参数),作为 lon,lat 参数。
functions > distance > referencePointParameter 要在查询中传递以用作参考位置的参数(使用 scoringParameter 查询参数)。
functions > distance > boostingDistance 以公里为单位指示与参考位置(提升范围结束)之间距离的数字。
functions > tag tag 计分函数用于影响基于文档和搜索查询中标记的文档的分数。 将提升与搜索查询有共同标记的文档。 搜索查询的标记作为每个搜索请求中的计分参数提供(使用 scoringParameter 查询参数)。
functions > tag > tagsParameter 要在查询中传递以指定特定请求的标记的参数(使用 scoringParameter 查询参数)。 该参数由逗号分隔的整个字词的列表组成。 如果列表中的给定标记本身是逗号分隔的列表,则可在查询时在字段上使用文本规范化器来去除逗号(将逗号字符映射到空格)。 此方法会“平展”列表,以便所有字词都是以逗号分隔的字词的单个长字符串。
functionAggregation 可选。 仅在函数已指定时适用。 有效值包括:sum(默认值)、average、minimum、maximum和 firstMatching。 搜索分数是从多个变量(包括多个函数)中计算的单个值。 此属性指示所有函数的提升如何组合到随后应用到基本文档分数的单个聚合提升中。 基本分数基于从文档和搜索查询计算得出的 tf-idf 值。
defaultScoringProfile 在执行搜索请求时,如果未指定任何计分概要文件,则使用默认计分(仅限 tf-idf)。

可以替代内置默认值,将自定义概要文件替换为在搜索请求中未提供特定配置文件时将使用的配置文件。

设置内插

通过内插,可设置用于计分的坡度形状。 由于评分从高到低,坡度总是在下降,但内插决定了下坡的曲线。 可以使用以下内插:

内插 说明
linear 对于在最大和最小范围内的项目,将按递减的方式进行提升。 Linear 是计分概要文件的默认内插。
constant 对于起始和结束范围内的项,将对排名结果应用恒定提升。
quadratic 与具有不断减小的提升的线性内插相比,二次方最初以较小的速度递减,然后在接近结束范围时,以更高的间隔递减。 tag 计分函数中不允许使用此内插选项。
logarithmic 与具有恒定递减提升的 Linear 内插相比,Logarithmic 最初以较大的速度递减,然后在接近结束范围时,以明显更小的间隔递减。 tag 计分函数中不允许使用此内插选项。

Constant, linear, quadratic, log10 lines on graph

设置 boostingDuration

boostingDurationfreshness 函数的属性。 使用它设置一个有效期,超过这个有效期之后,针对特定文档的提升将停止。 例如,要在 10 天促销期内提升某个产品系列或品牌,应针对这些文档将 10 天期限指定为 "P10D"。

boostingDuration 必须设置为 XSD "dayTimeDuration" 值(ISO 8601 持续时间值的受限子集)的格式。 它的模式为:“P[nD][T[nH][nM][nS]]”。

下表提供几个示例。

持续时间 boostingDuration
1 天 "P1D"
2 天 12 小时 "P2DT12H"
15 分钟 "PT15M"
30 天 5 小时 10 分钟 6.334 秒 "P30DT5H10M6.334S"

有关更多示例,请参阅 XML 架构:数据类型(W3.org 网站)

扩展示例

下面的示例演示具有两个计分概要文件(boostGenrenewAndHighlyRated)的索引架构。 针对此索引的任何查询(包含任一概要文件作为查询参数)将使用此概要文件对结果集进行计分。

boostGenre 概要文件使用加权文本字段,提升在“albumTitle”、“genre”和“artistName”字段中找到的匹配项。 这些字段分别提升了 1.5、5 和 2。 genre 为何比其他字段提升更高? 如果对某种程度上为同类的数据执行搜索(正如 musicstoreindex 中的“genre”一样),可能需要在相对权重中具有更大的差异。 例如,在 musicstoreindex 中,“rock”既作为流派显示,又显示在采用相同组句方式的流派说明中。 如果希望流派的权重在流派说明之上,genre 字段将需要更高的相对权重。

{  
  "name": "musicstoreindex",  
  "fields": [  
    { "name": "key", "type": "Edm.String", "key": true },  
    { "name": "albumTitle", "type": "Edm.String" },  
    { "name": "albumUrl", "type": "Edm.String", "filterable": false },  
    { "name": "genre", "type": "Edm.String" },  
    { "name": "genreDescription", "type": "Edm.String", "filterable": false },  
    { "name": "artistName", "type": "Edm.String" },  
    { "name": "orderableOnline", "type": "Edm.Boolean" },  
    { "name": "rating", "type": "Edm.Int32" },  
    { "name": "tags", "type": "Collection(Edm.String)" },  
    { "name": "price", "type": "Edm.Double", "filterable": false },  
    { "name": "margin", "type": "Edm.Int32", "retrievable": false },  
    { "name": "inventory", "type": "Edm.Int32" },  
    { "name": "lastUpdated", "type": "Edm.DateTimeOffset" }  
  ],  
  "scoringProfiles": [  
    {  
      "name": "boostGenre",  
      "text": {  
        "weights": {  
          "albumTitle": 1.5,  
          "genre": 5,  
          "artistName": 2  
        }  
      }  
    },  
    {  
      "name": "newAndHighlyRated",  
      "functions": [  
        {  
          "type": "freshness",  
          "fieldName": "lastUpdated",  
          "boost": 10,  
          "interpolation": "quadratic",  
          "freshness": {  
            "boostingDuration": "P365D"  
          }  
        },  
        {
          "type": "magnitude",  
          "fieldName": "rating",  
          "boost": 10,  
          "interpolation": "linear",  
          "magnitude": {  
            "boostingRangeStart": 1,  
            "boostingRangeEnd": 5,  
            "constantBoostBeyondRange": false  
          }  
        }  
      ]  
    }  
  ],  
  "suggesters": [  
    {  
      "name": "sg",  
      "searchMode": "analyzingInfixMatching",  
      "sourceFields": [ "albumTitle", "artistName" ]  
    }  
  ]   
}  

另请参阅