共用方式為

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

计分概要文件用于根据条件来提升匹配文档的排名。 本文介绍如何指定和分配计分概要文件,以便根据提供的参数提升搜索分数。 可以根据以下内容创建计分概要文件:

  • 加权字符串字段,其中提升基于指定字段中找到的匹配项。 例如,在“主题”字段中找到的匹配项被认为比“说明”字段中找到的匹配项更相关。

  • 数值字段的函数,包括日期和地理坐标。 数值内容函数支持提升距离(适用于地理坐标)、新鲜度(适用于日期时间字段)、范围和数量级。

  • 字符串集合的函数(标签)。 如果集合中的任何项都与查询匹配,标记函数将提升文档的搜索分数。

可以通过在 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中介绍了查询参数(包括)。

有关更多方案,请参阅本文中 有关新鲜度、距离加权文本和函数 的示例。

将评分概要文件添加到搜索索引

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

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

  3. 提供符合 命名约定的名称。

  4. 指定提升条件。 单个配置文件可以包含文本加权字段和/或函数

应使用有助于证明或反驳给定配置文件有效性的数据集来迭代工作。

可以在 Azure 门户中定义计分配置文件,如以下屏幕截图所示,也可以通过 REST API 或 Azure SDK 以编程方式定义,例如 .NETPython 客户端库中的 ScoringProfile 类。

显示 Azure 门户中的“添加计分概要文件”选项的屏幕截图。

模板

本部分演示计分概要文件的语法和模板。 有关属性的描述,请参阅 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.DoubleEdm.Int 字段结合使用。 对于 magnitude 函数,如果想要反转模式(例如,将价格较低项提升至价格较高项之上),可以将范围反转为从高到低。 假设价格范围从 100 美元到 1 美元,可以将 boostingRangeStart 设为 100、boostingRangeEnd 设为 1 以提升价格较低的项。 当想要提高利润率、评级、单击次数、下载次数、最高价格、最低价格或下载次数时使用。 当两个项目相关时,将首先显示具有较高分级的项目。
标签 按搜索文档和查询字符串共有的标记提升。 tagsParameter 中提供了标记。 此函数仅可与类型为 Edm.StringCollection(Edm.String) 的搜索字段结合使用。 当有标签字段时使用。 如果列表中的给定标记本身是逗号分隔的列表,则可在查询时在字段上使用文本规范化器来去除逗号(将逗号字符映射到空格)。 此方法将列表展开,以使所有项成为一个以逗号分隔的长字符串。

数量级是字段值(如日期或位置)与引用点(如“now”或目标位置)之间的计算距离。 它是评分函数的输入,并确定应用的提升量。

新鲜度和距离评分是基于幅度评分的特殊情况,其中数量级是通过日期时间或地理字段自动计算的。 为了实现直观地提升较新值或更接近值而不是较旧值或更远值,请使用负值提升(请参阅示例了解更多详情)。

使用函数的规则

  • 函数只能应用于被归为 filterable 的字段。
  • 函数类型(“freshness”、“magnitude”、“distance”、“tag”)必须为小写。
  • 函数不能包含 null 值或空值。
  • 每个函数定义中函数只能有一个字段。 若要在同一个配置文件中使用两次度量值,请提供两个定义度量值,每个字段一个。

设置内插

插值设定了用于提升新鲜度和距离的斜率形状。

当提升值为正值时,评分高到低,斜率始终下降。 随着负提升,斜率正在增加(较新的文档获得更高的分数)。 插值值决定了上升或下降斜率的曲线,以及在响应日期或距离变化时,提升分数变化的幅度。 可以使用以下内插:

内插 说明
linear 对于最大和最小范围内的项,将按递减的方式进行提升。 负面加权会按比例降低较旧文件的优先级。 适用于相关性逐渐下降的情况。 Linear 是计分概要文件的默认内插。
constant 对于起始和结束范围内的项,将对排名结果应用恒定提升。 对于新鲜度和距离,对范围内的所有文档应用相同的负权重调整。 当你想要一个无论年龄的固定罚则时,使用该策略。
quadratic 二次函数最初以较慢的速度下降,然后当接近结束范围时,它会以更快的速度下降。 为了进行负向调整,它对年龄较大的文件随着时间的推移给予越来越多的惩罚。 如果想要强烈支持最新文档并大幅降级较旧的文档,请使用此功能。 标记评分函数中不允许使用此内插选项。
logarithmic 对数函数最初以较快的速度下降,而当接近末端时,下降的速度则显著减缓。 对于负面提升,它首先更严厉地惩罚较旧的文件,然后减少。 理想情况下,你希望对最新内容具有很强的偏好,但随着文档年龄的增长,敏感度较低。 标记评分函数中不允许使用此内插选项。

关系图上的常数、线性、二次、log10 线

设置 freshness 函数的 boostingDuration

boostingDurationfreshness 函数的属性。 使用它来设置一个过期时间段,之后特定文档的提升将停止。 例如,要在 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" 定义评估新鲜度的时间范围。

示例:通过加权文本和函数增强

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

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" ]  
    }  
  ]   
}