计分概要文件用于根据条件来提升匹配文档的排名。 本文介绍如何指定和分配计分概要文件,以便根据提供的参数提升搜索分数。 可以根据以下内容创建计分概要文件:
加权字符串字段,其中提升基于指定字段中找到的匹配项。 例如,在“主题”字段中找到的匹配项被认为比“说明”字段中找到的匹配项更相关。
数值字段的函数,包括日期和地理坐标。 数值内容函数支持提升距离(适用于地理坐标)、新鲜度(适用于日期时间字段)、范围和数量级。
字符串集合的函数(标签)。 如果集合中的任何项都与查询匹配,标记函数将提升文档的搜索分数。
可以通过在 Azure 门户中编辑其 JSON 定义或通过任何 Azure SDK 中的 创建或更新索引 REST 或等效索引更新 API 等 API 以编程方式将计分配置文件添加到索引。 没有索引重新生成要求,因此可以添加、修改或删除评分配置文件,而不会影响索引文档。
先决条件
- 包含文本或数字(非函数)字段的搜索索引。
计分概要文件的规则
可以在 关键字搜索、 矢量搜索、 混合搜索和 语义搜索(重新调整)中使用计分配置文件。 但是,计分配置文件仅适用于非函数字段,因此请确保索引具有可以提升或加权的文本或数值字段。
在一个索引中可以具有最多 100 个计分概要文件(请参阅服务限制),但在任何给定查询中,一次只能指定一个概要文件。
计分概要文件定义
评分配置文件在索引架构中定义。 它由加权字段、函数和参数组成。
以下定义展示了名为“geo”的简单概要文件。 此示例用于提升在“hotelName”字段中具有搜索词的结果。 它还使用 distance
函数优先提升在当前位置 10 公里范围内的结果。 如果有人搜索“inn”,而“inn”一词恰好是某个酒店名称的一部分,那么在当前位置 10 公里半径范围内包含这些酒店的相关文档会在搜索结果中排名更高。
"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”具有单连接号 (-
) 分隔符。 它后跟经度和纬度坐标,其中经度为负值。
POST /indexes/hotels/docs&api-version=2024-07-01
{
"search": "inn",
"scoringProfile": "geo",
"scoringParameters": ["currentLocation--122.123,44.77233"]
}
scoringParameters
中介绍了查询参数(包括)。
有关更多方案,请参阅本文中 有关新鲜度、距离 和 加权文本和函数 的示例。
将评分概要文件添加到搜索索引
应使用有助于证明或反驳给定配置文件有效性的数据集来迭代工作。
可以在 Azure 门户中定义计分配置文件,如以下屏幕截图所示,也可以通过 REST API 或 Azure SDK 以编程方式定义,例如 .NET 或 Python 客户端库中的 ScoringProfile 类。
模板
本部分演示计分概要文件的语法和模板。 有关属性的描述,请参阅 REST API 参考。
"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 or negative 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) "...",
使用文本加权字段
当字段上下文很重要且查询包含 searchable
字符串字段时,使用文本加权字段。 例如,如果查询包含“airport”一词,则可能希望在 HotelName 字段中出现“airport”,而不是在描述字段中。
加权字段是由一个 searchable
字段和一个用作乘数的正数组成的名称-值对。 如果 HotelName 的原始字段分数为 3,该字段的提升分数将变为 6,从而提升父文档本身的总体分数。
"scoringProfiles": [
{
"name": "boostSearchTerms",
"text": {
"weights": {
"HotelName": 2,
"Description": 5
}
}
}
]
使用函数
当简单的相对权重不足或不适用时,请使用函数,例如距离和新鲜度的情况(即对数值数据的计算)。 可以为每个计分概要文件指定多个函数。 有关 Azure AI 搜索中使用的 EDM 数据类型的详细信息,请参阅支持的数据类型。
函数 | 说明 | 用例 |
---|---|---|
距离 | 按距离或地理位置提升。 此函数仅可与 Edm.GeographyPoint 字段结合使用。 |
用于“在我附近查找”方案。 |
新鲜 | 按照日期/时间字段 (Edm.DateTimeOffset ) 中的值进行提升。
设置 boostingDuration 来指定表示发生提升的时间跨度的值。 |
当想要按较新或较旧的日期提升时使用。 排列日历事件等具有未来日期的项,以便接近当前日期的项可以排在距离当前日期较远的将来的项之上。 范围的一端固定为当前时间。 若要扩大过去的时间范围,请使用正 boostingDuration。 要提升将来的时间范围,请使用负的 boostingDuration。 |
量级 | 根据数字字段的值范围改变排名。 该值必须是整数或浮点数。 对于星级评分 1 到 4,这里应为 1。 对于超过 50% 的利润率,这里应为 50。 此函数仅可与 Edm.Double 和 Edm.Int 字段结合使用。 对于 magnitude 函数,如果想要反转模式(例如,将价格较低项提升至价格较高项之上),可以将范围反转为从高到低。 假设价格范围从 100 美元到 1 美元,可以将 boostingRangeStart 设为 100、boostingRangeEnd 设为 1 以提升价格较低的项。 |
当想要提高利润率、评级、单击次数、下载次数、最高价格、最低价格或下载次数时使用。 当两个项目相关时,将首先显示具有较高分级的项目。 |
标签 | 按搜索文档和查询字符串共有的标记提升。
tagsParameter 中提供了标记。 此函数仅可与类型为 Edm.String 和 Collection(Edm.String) 的搜索字段结合使用。 |
当有标签字段时使用。 如果列表中的给定标记本身是逗号分隔的列表,则可在查询时在字段上使用文本规范化器来去除逗号(将逗号字符映射到空格)。 此方法将列表展开,以使所有项成为一个以逗号分隔的长字符串。 |
数量级是字段值(如日期或位置)与引用点(如“now”或目标位置)之间的计算距离。 它是评分函数的输入,并确定应用的提升量。
新鲜度和距离评分是基于幅度评分的特殊情况,其中数量级是通过日期时间或地理字段自动计算的。 为了实现直观地提升较新值或更接近值而不是较旧值或更远值,请使用负值提升(请参阅示例了解更多详情)。
使用函数的规则
- 函数只能应用于被归为
filterable
的字段。 - 函数类型(“freshness”、“magnitude”、“distance”、“tag”)必须为小写。
- 函数不能包含 null 值或空值。
- 每个函数定义中函数只能有一个字段。 若要在同一个配置文件中使用两次度量值,请提供两个定义度量值,每个字段一个。
设置内插
插值设定了用于提升新鲜度和距离的斜率形状。
当提升值为正值时,评分高到低,斜率始终下降。 随着负提升,斜率正在增加(较新的文档获得更高的分数)。 插值值决定了上升或下降斜率的曲线,以及在响应日期或距离变化时,提升分数变化的幅度。 可以使用以下内插:
内插 | 说明 |
---|---|
linear |
对于最大和最小范围内的项,将按递减的方式进行提升。 负面加权会按比例降低较旧文件的优先级。 适用于相关性逐渐下降的情况。 Linear 是计分概要文件的默认内插。 |
constant |
对于起始和结束范围内的项,将对排名结果应用恒定提升。 对于新鲜度和距离,对范围内的所有文档应用相同的负权重调整。 当你想要一个无论年龄的固定罚则时,使用该策略。 |
quadratic |
二次函数最初以较慢的速度下降,然后当接近结束范围时,它会以更快的速度下降。 为了进行负向调整,它对年龄较大的文件随着时间的推移给予越来越多的惩罚。 如果想要强烈支持最新文档并大幅降级较旧的文档,请使用此功能。 标记评分函数中不允许使用此内插选项。 |
logarithmic |
对数函数最初以较快的速度下降,而当接近末端时,下降的速度则显著减缓。 对于负面提升,它首先更严厉地惩罚较旧的文件,然后减少。 理想情况下,你希望对最新内容具有很强的偏好,但随着文档年龄的增长,敏感度较低。 标记评分函数中不允许使用此内插选项。 |
设置 freshness 函数的 boostingDuration
boostingDuration
是 freshness
函数的属性。 使用它来设置一个过期时间段,之后特定文档的提升将停止。 例如,要在 10 天促销期内提升某个产品系列或品牌,应针对这些文档将 10 天期限指定为 "P10D"。
boostingDuration
必须设置为 XSD "dayTimeDuration" 值(ISO 8601 持续时间值的受限子集)的格式。 它的模式为:“P[nD][T[nH][nM][nS]]”。
下表提供几个示例。
持续时间 | 提升时长 |
---|---|
1 天 | “P1D” |
2 天 12 小时 | “P2DT12H” |
15 分钟 | “PT15M” |
30 天 5 小时 10 分钟 6.334 秒 | “P30DT5H10M6.334S” |
1 年 | “365D” |
有关更多示例,请参阅 XML 架构:数据类型(W3.org 网站)。
示例:通过新鲜度或距离提升
在 Azure AI 搜索中,新鲜度评分将日期和数值转换为单个数值,表示文档日期与当前时间的时间差。 日期越大,数量级越大。 这会导致反直观行为:最近的文档权重较小,这意味着正面的提升因素偏向较旧的文档,除非明确反转提升方向。
同样的逻辑适用于距离提升,其中更远的位置产生更大的数量级。
若要通过新鲜度或距离提升,请使用负提升值来确定较新的日期或更近的位置的优先级。 通过负助推因子来反转提升方向会惩罚更大的数量级(较旧的日期),从而有效地增加最近的数量。 例如,假设一个提升函数,例如 b * (1 - x)
(其中 x
是标准化的幅度,从 0 到 1),该函数为较小的幅度(即较新的日期)提供更高的分数。
助推曲线的形状(常数型、线性型、对数型、二次型)会影响得分在整个分布范围内的变化速率。 使用负因子时,曲线的行为会翻转,例如,二次曲线在较旧日期的减速速度更慢,而对数曲线在远端更急剧地移动。
下面是一个示例评分模型,演示如何使用负向增强来解决不直观的新鲜度评分,并解释新鲜度评分中数量级的影响。
"scoringProfiles": [
{
"name": "freshnessBoost",
"text": {
"weights": {
"content": 1.0
}
},
"functions": [
{
"type": "freshness",
"fieldName": "lastUpdated",
"boost": -2.0,
"interpolation": "quadratic",
"parameters": {
"boostingDuration": "365D"
}
}
]
}
]
-
"fieldName": "lastUpdated"
是用于计算新鲜度的日期/时间字段。 -
"boost": -2.0
是一个负提升因子,可反转默认行为。 由于较旧的日期具有更大的数值,这会减弱它们,从而增强较新的文档。 -
"interpolation": "quadratic"
这意味着,对于离当前日期更近的文档来说,提升效果更强,对于较旧的文档来说,效果会更加快速地减弱。 -
"boostingDuration": "365D"
定义评估新鲜度的时间范围。
示例:通过加权文本和函数增强
下面的示例演示具有两个计分概要文件(boostGenre
、newAndHighlyRated
)的索引架构。 任何针对此索引的查询,如果将任一配置文件作为查询参数,则会使用该配置文件来对结果集进行评分。
boostGenre
概要文件使用加权文本字段,提升在“albumTitle”、“genre”和“artistName”字段中找到的匹配项。 这些字段分别提升了 1.5、5 和 2。 genre 为何比其他字段提升更高? 如果对有点同质的数据进行搜索(与 musicstoreindex 中的“流派”一样),则可能需要相对权重的较大方差。 例如,在 musicstoreindex 中,“rock”既作为流派显示,又显示在采用相同组句方式的流派说明中。 如果希望流派超过流派描述,流派字段需要更高的相对权重。
{
"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" ]
}
]
}