构建一个控制平面来治理电子商务搜索

0 阅读18分钟

作者:来自 Elastic Alexander MarquardtHonza Král 及 Taylor Roy

如何为 ecommerce 构建一个受治理的控制平面,将相互冲突的搜索策略组合成一个单一的执行计划(无需代码更改)。

www.bilibili.com/video/BV15E… www.bilibili.com/video/BV15j…

https://www.bilibili.com/video/BV1vjRGBaE6S 标题

刚接触 Elasticsearch 吗?加入我们的 Elasticsearch 入门网络研讨会。你也可以现在开始一个免费的云试用,或者在你的本地机器上试用 Elastic。


本系列的第 1 部分第 2 部分已经说明了为什么 ecommerce 搜索需要一个治理层,这是位于用户查询和检索引擎之间的一个决策层,用于分类意图、执行约束,并路由到正确的检索策略(例如, BM25、语义、混合)。本文展示了如何使用一个简单的架构原语来构建这一层,其中查询解释策略被存储为文档,并在查询时通过快速反向匹配进行检索。由于新的检索策略(例如,“提升品牌 X” 或 “仅显示类别 Y”)不需要代码更改,其结果是一个路由层,在策略演进时保持稳定,并在高风险环境中确保检索引擎的安全。如果你想在继续阅读之前查看该架构的最终效果,请查看这个视频: 在几秒内修复搜索相关性:介绍 PRISM

为什么查询解释经常是一个挑战?

将策略以代码形式存储(应用层中的 if/else 代码块)会产生成千上万行脆弱的逻辑,这些逻辑没有任何索引用于在查询时高效检索策略。迭代速度很慢(一次查询行为变更可能需要六周的发布周期),责任归属不清晰(为什么结果发生了变化?),并且业务用户无法在没有工程团队参与的情况下修改搜索行为。如下图左侧所示:

将策略作为数据存储在 Elasticsearch 索引中,如上图右侧所示。这种方法解决了与硬编码查询解析逻辑相关的所有问题。然而,要实现这一点,你需要一种方式来快速确定哪些策略匹配用户查询,以及当策略之间发生冲突时应如何解决。这正是受治理的控制平面发挥作用的地方。

控制平面模式

一个受治理的控制平面位于原始用户查询和 Elasticsearch 检索之间。它接收用户文本作为输入,其输出是一个执行计划,其中包含过滤条件、提升规则以及检索路由决策。

一个控制平面流水线由以下部分组成:

  • 用户查询:用户输入一个他们在寻找内容的字符串,例如 “橙子” 或 “送给爷爷的礼物”。
  • 策略查找:将用户查询与策略索引进行匹配。
  • 返回匹配策略:从策略索引中返回与用户查询匹配的策略。
  • 策略应用:控制平面分析这些返回的策略,并将匹配到的策略组合成一个统一的执行计划,其中包括过滤条件、提升规则、覆盖规则和护栏机制,并选择合适的检索方式(例如,词法检索 versus 语义检索 versus 混合检索)。
  • 执行:将修改后的、具备意图感知的 Elasticsearch 查询交由应用执行,并在商品目录索引上运行。
  • 解释(可选):除了生成一个能够提供业务与意图对齐结果的查询之外,控制平面还可以提供一个可选的可解释性载荷,用于展示哪些策略被触发以及它们是如何被组合的。

为用户搜索字符串找到应该应用哪些策略,需要一个快速的反向匹配原语,我们通过 percolator 查询来解决这个问题。在检索到相关策略之后,将多个匹配策略合并为一个统一执行计划需要一个判断框架:优先级、冲突策略、已消费短语追踪,以及按顺序而不是独立执行策略的级联转换。此外,还需要选择最合适的检索技术(例如,“橙子” 使用 BM25,而 “送给爷爷的礼物” 使用语义搜索)。

策略查找:在搜索商品之前检查查询

当购物者输入查询时,使用受治理控制平面的搜索系统不会直接将该查询发送到商品目录中执行。首先,系统会将查询与一组已存储的策略进行匹配检查,并根据查询意图与业务优先级对其进行调整。

策略结构

每条策略都是一个简单的文档,定义两件事:

  • 匹配条件:什么样的查询文本会触发该策略。可以是精确短语、单个词、模式,或它们的组合。
  • 动作:当策略被触发时执行什么操作。可以是应用类别过滤、排除商品、提取价格约束,或改变检索策略。

系统会找出所有匹配的策略,将它们组合成一个执行计划,然后才执行商品搜索。整体来看,这些策略就像一个熟悉业务的门店导购,理解你在找什么,并带你去正确的货架。

策略模式

本系列前几篇文章已经介绍了策略在实践中的例子:将 “橙子 ”限制在生鲜类别,将 “不含花生” 作为排除条件,以及将“送给爷爷的礼物”路由到语义检索。关键的架构点在于,在每种情况下,查询都会在商品搜索开始之前先与已存储策略进行检查。策略决定应用哪些约束、修改哪些文本,以及使用哪种检索策略。在策略应用之后,会生成一个新的重写查询,然后才对商品目录执行搜索。

为什么这很快

一个企业级 ecommerce 系统可能有数百万个商品,但只有数百或数千条策略。策略查找步骤是在一个小型、精选的索引上进行搜索,而不是在整个商品目录上,因此速度很快。而且由于策略作为数据存储在独立索引中,新增策略的运营人员不需要接触应用代码,优化商品搜索的工程师也不需要接触策略索引,两者可以独立演进。

上面的例子描述的是概念层面的行为。在底层,策略查找是通过 Elasticsearch 的 percolator 查询类型实现的,它专门用于这种模式:将输入文本与一组已存储查询进行匹配。本系列第 4 部分将深入讲解 percolator 的实现细节,包括索引 mapping、边界标记,以及基于高亮的短语追踪。在第 4 部分深入介绍查找机制之后,我们将继续讨论一个策略文档实际包含什么,以及控制平面如何将多个策略组合成一个统一的执行计划。

示例策略

现在我们已经从概念上了解了策略的作用,接下来看看它们的实际内容。下面的两个策略被刻意设计为彼此冲突,用于展示后续章节中描述的冲突解决系统。

廉价巧克力

下面的策略会检测用户是否提交了包含“cheap chocolate”的搜索。如果是,则将结果限制在“Chocolates”和“Milk chocolates”类别中。该策略还会应用 2 美元的价格过滤条件。此外,请注意该策略的优先级为 210;在我们更详细讨论冲突解决时会再回到这一点。

此处展示的 filter mode 和冲突策略设置(hard_filter、soft_boost、restrict、override)将在下面的冲突解决部分中详细说明。

当上述策略被激活时,对 “cheap chocolate” 的搜索会遵循 2 美元的价格过滤条件,并将结果限制在 “Chocolates” 和 “Milk chocolates” 类别中。示例结果如下:

圣诞巧克力

下面的策略是一个可以想象在圣诞节期间应用的示例策略。该示例将结果限制为 “圣诞食品与饮料” 和 “圣诞甜点”,并对属于 “圣诞倒数日历(Advent calendars)”类别的商品进行提升,同时应用低于 7 美元的价格过滤,以聚焦于可负担的季节性商品。此外,请注意该策略的优先级为 300。我们将在后续关于冲突解决的部分中再回到这一点。

当上述策略在没有任何冲突策略的情况下被激活时,对“chocolate”的搜索会遵循 7 美元的价格过滤条件,并将结果限制在“Christmas food and drinks”和 “Christmas sweets” 类别中,同时提升任何标记为 “Advent calendars” 的商品。示例结果如下:

合并匹配的策略

上面描述的策略查找只是故事的一半。另一半是当多个策略同时匹配同一个查询时会发生什么。

在任何非平凡的部署中,一个查询通常会同时触发多个策略。“cheap chocolate” 会同时匹配我们上面展示的两个策略。每个策略单独来看都是正确的。但挑战在于如何将它们组合成一个统一的执行计划,既不产生冲突、不重复计算,也不会让某个策略悄悄覆盖另一个策略的效果。

这不是一个检索问题,而是一个判断问题。系统必须决定:

  • 应用顺序:如果一个否定策略从查询中移除了 “without peanuts”,价格策略是基于原始文本还是修改后的文本?
  • 过滤冲突:如果两个策略设置了不同的价格上限,哪个会生效?失败的策略是被静默丢弃,还是优雅地降级为软提升(soft boost)?
  • 短语归属:如果两个策略都匹配了同一个词,而第一个策略已经“消耗”了它,那么第二个策略是否还应该触发?

一个简单的实现方式(对所有匹配策略独立应用并合并结果)一旦策略之间开始相互作用就会失效。架构需要一个明确的模型来定义策略如何组合。本节接下来的两部分将描述这个模型:一个优先级与冲突解决框架,以及一个级联变换模型,使策略交互具有确定性。

关键洞察在于:策略应用不是一组独立操作,而是一个级联变换过程。每个策略都接收由更高优先级策略产生的重写状态,并在其基础上继续变换:

初始状态 → [策略 A] → 状态' → [策略 B] → 状态'' → ... → 执行计划

这个状态包含重写后的查询文本、累积的过滤条件、当前意图以及任何同义词扩展。高优先级策略可以从查询中移除文本,而后续所有策略看到的都是修改后的查询,而不是原始查询。上下文是累积的,顺序是有意义的。

优先级与冲突解决:确定性至关重要

具体的冲突策略是一种设计选择。不同组织可能会根据自身业务需求以不同方式解决冲突。下面的方法展示了控制平面所需的一种判断框架。关键点不在于这些具体策略本身,而在于系统必须具备显式且确定性的策略,而不是让冲突通过不可预测的交互自行解决。

优先级排序

策略按照优先级排序(从高到低)。当多个策略匹配同一个查询时,它们按优先级顺序执行。如果两个策略尝试设置同一个过滤字段,则该字段由优先级更高的策略所声明的策略优先。如果有多个被触发的策略具有相同优先级,则优先级由策略 ID 更高的策略决定(相当于赋予更高优先级);这种设计确保在冲突发生时行为是确定性的。

按字段解析,而非按策略解析

一个关键设计原则:冲突解决是按字段(例如 brand、category 或 description)进行的,而不是按策略进行。当两个策略在特定字段上产生重叠过滤时,仅这些具体字段会受到冲突解决策略的影响,并且冲突解决策略由最高优先级的匹配策略定义。两个策略中不冲突的字段会完整保留。

这一点很重要,因为如果采用按策略的方式,一旦策略中只有某个字段冲突,就必须整体接受或拒绝整个策略。

按字段解析可以最大化保留有用的约束信息。

每个过滤字段的三个设置

每个策略中的过滤字段都有三个独立设置:

Filter mode(过滤模式):在没有冲突时如何应用过滤。

  • hard_filter(默认):作为 Elasticsearch bool.filter 子句应用。这用于完全排除不相关的商品。例如,将“oranges”的搜索限制在生鲜类别,可以排除橙汁和橙子果酱等结果。不匹配的文档会被完全排除。
  • soft_boost:作为 Elasticsearch function_score 权重应用,并带有可配置 boost_weight。匹配的文档会获得排名提升,但不匹配的文档不会被排除。这适用于提升某个品牌但不排除其他品牌的情况。

Conflict strategy(冲突策略)

当低优先级策略设置了同一个字段时的处理方式:

  • override:高优先级策略胜出,低优先级值被完全丢弃。适用于所有字段类型。
  • restrict:采用更严格的数值(例如 price__max 取更低上限,price__min 取更高下限)。仅适用于数值范围字段。
  • merge:将两个值合并为并集。仅适用于非数值字段。
  • soft_boost:将冲突的过滤转换为 function_score 权重,而不是硬过滤,并使用可配置 boost_weight。关于 function_score 加权的更多细节,请参考 Elasticsearch 中通过乘性加权影响 BM25 排序。这仅适用于非否定字段。

Value(值):实际的过滤值(例如类别列表、价格阈值)。

按字段类型划分的策略:并非所有策略都适用于所有字段类型。例如,排除条件本质上是二值的,因此无法进行 soft-boost。下表展示了每种字段类型可用的策略。

字段类型可用策略默认值
否定字段(__not,__match__not)override,mergeoverride
数值范围字段(__max,__min,__gt,__lt)restrict,override,soft_boostrestrict
其他所有字段(keyword,text)soft_boost,override,mergesoft_boost

否定字段不能被 soft-boost,因为 “排除” 本质上是二元的。将 “永不展示罐头食品” 转换为 “稍微不那么偏好罐头食品”,会从根本上改变语义;来自 “罐头食品” 的商品仍然会出现,只是排名稍微靠后,这就违背了排除的初衷。

一个具体例子:在圣诞活动期间搜索“cheap chocolate”

假设一个商品运营人员已经创建了我们之前展示的两个巧克力策略,一个是低优先级的 “cheap chocolate” 策略,另一个是在圣诞期间启用的、更高优先级的巧克力相关策略。如果这两个策略同时启用,那么它们如何组合取决于更高优先级策略所定义的 filter mode 和冲突策略。如果前面讨论的两个策略同时启用,它们将按如下方式组合:

这展示了两个冲突,一个发生在类别上,一个发生在价格上。需要注意的是,在该变换之后将要执行的查询具有以下特征:

  • 仅显示 “Christmas foods and drinks” 和 “Christmas sweets” 类别中的商品。
  • 在这些类别中,如果商品同时被标记为 “Advent calendars” 类别,则会获得 3 倍提升。
  • 应用 $2 的价格过滤条件,该条件来自低优先级策略(因为高优先级策略在冲突时指定使用 “Restrict”)。
  • “cheap” 这个词被移除,只返回匹配 “chocolate” 的商品。

在启用这两个策略后,“cheap chocolate” 的返回结果类似如下图所示:

放宽约束

也许零售商在圣诞期间并不希望排除 “Chocolates” 和 “Milk chocolates” 类别中的商品。圣诞策略中的设置可能过于激进,并且无意中移除了 “cheap chocolate” 策略所应用的类别。这正是一个例子,说明在某些情况下,将低优先级策略与发生冲突的高优先级策略进行组合可能更为理想。例如,我们可以修改圣诞巧克力促销策略,使其在冲突时不再使用 “Override”,而改为 soft boost。该策略的修改如下:

在此修改之后,“cheap chocolate” 的查询重写转换流水线执行如下所示:

在冲突使用 soft boost 之后,冲突过滤条件不会被丢弃,而是会被转换为提升权重。该变换之后在商品目录上执行的查询具有以下特征:

  • 由于更高优先级策略在“冲突时处理方式”中指定为 “Soft boost”,因此冲突会被转换为提升权重,具体如下:
    • 来自 “Christmas foods and drinks” 和 “Christmas sweets” 类别的商品将获得 1 倍提升。
    • 来自 “Chocolates” 和 “Milk chocolates” 类别的商品将获得 3 倍提升。
  • 与前一个示例相同,如果商品同时被标记为 “Advent calendars” 类别,则还会额外获得 3 倍提升。
  • 与前一个示例相同,应用 $2 的价格过滤条件。
  • “cheap” 一词被移除,仅返回匹配 “chocolate” 的商品。

在采用更宽松过滤方式后,结果如下所示:

从高优先级策略中覆盖价格

或者,零售商可能希望在圣诞期间允许展示稍贵一些的巧克力,将最高价格提高到 $7。为了确保当有人搜索 “cheap chocolates” 时,圣诞巧克力策略中的最高价格不会被覆盖,我们可以将价格字段的冲突模式从 “restrict” 改为 “override”,如下所示:

这与前一个示例类似,区别在于最大价格被设置为来自更高优先级策略的 $7 值,因为该策略在冲突时指定了 “Override”。随着圣诞价格过滤条件获得优先权,结果如下所示:

这三种变化(override、soft_boost,以及价格字段上的 override)展示了系统的一个关键特性:商品运营人员可以通过修改单个策略中单个字段的一个设置,来改变两个策略之间的交互方式,而无需部署任何代码。冲突策略本身就是控制业务行为的“调节旋钮”。

短语消耗(consumed phrase)跟踪

还存在一种更隐蔽的冲突形式:两个策略匹配了同一个短语。如果一个高优先级策略从查询中移除了 “without peanuts”,那么一个同样匹配 “without” 的低优先级策略就已经没有可作用的内容了。系统会检测该匹配短语是否仍然存在于重写后的查询中,如果已经不存在,则跳过该低优先级策略。

意图策略(intent policies)不受短语消耗影响:它们基于原始查询匹配来决定检索策略,而不受高优先级策略删除文本的影响。

优先级排序、按字段冲突解决以及短语消耗跟踪共同构成了控制平面的确定性组合模型。在此基础之上,系统才能做出一个在没有这些机制时会很危险的路由决策。

治理让检索策略更安全

一个关键洞察是:路由到正确的检索方式(文本、语义或混合)发生在治理之后。如果策略已经强制了 “生鲜类别”,那么语义检索就会安全得多,因为候选集合已经被约束过了。在 500 个商品上做语义搜索,与在 500,000 个 SKU 上做语义搜索,是完全不同的风险级别。治理在检索开始之前就缩小了影响范围。

例如,如果没有治理,一个语义查询 “富含维生素 C 且低于 $4 的水果”,除了水果之外,还可能返回维生素瓶、胡萝卜和青椒。而控制平面可以确保这些不相关结果甚至不会进入语义扩展的候选范围。

在这一约束之下,控制平面会应用务实的路由逻辑:

  • 对导航型与头部查询(head queries)使用 lexical,在这些场景中确定性和精确匹配更重要。
  • 对描述型探索查询使用 semantic,在这些场景中概念匹配更有价值。
  • 在已经施加约束且业务接受更高召回率时,选择性使用 hybrid

从架构到实现

受治理的控制平面将业务意图转化为确定性、可组合的执行计划,而不需要将这些逻辑嵌入应用代码中。策略是数据:在查询时被匹配,通过显式的按字段冲突策略进行解析,并以级联变换的方式应用,从而生成可解释的结果。Elastic Services Engineering 已经为企业 ecommerce 团队构建并部署了这一架构,使用可复用的模式和加速器,将从概念到生产的路径大幅压缩。你可以在 YouTube 上观看我们控制平面实现的演示视频:在几秒内修复搜索相关性:介绍 PRISM

本系列下一篇内容

下一篇文章将进入实现层面的实践:深入讲解 Elasticsearch percolator 如何驱动策略查找,包括索引 mapping、边界标记、基于高亮的短语追踪,以及具体的查询示例。

将受治理的 ecommerce 搜索付诸实践

本文中描述的控制平面架构(按字段冲突解决、级联策略变换,以及治理约束下的检索路由)由 Elastic Services Engineering 设计并构建。本系列中展示的每一种模式、截图和转换流水线都来自 Elastic Services Engineering 构建的真实系统,并已在企业级商品目录规模下验证。

如果你希望在 Elasticsearch 上实现一个受治理、基于策略的控制平面,Elastic Services 可以帮助你更快完成落地。

参与讨论

如果你对搜索治理、检索策略或 ecommerce 搜索架构有疑问,可以加入更广泛的 Elastic 社区讨论

这份内容对你有多大帮助?

原文:www.elastic.co/search-labs…