NEAREST BY 子句

适用于:检查标记为是 Databricks Runtime 18.3 及更高版本

JOIN扩展自定义距离或相似性表达式上的 top-k 排名。 对于查询(左)table_reference的每一行,它根据ranking_expression目标表(右)表中的顶部num_results匹配行,以串联行的形式返回它们。

ranking_expression 可以是对两个表中的一对行进行评分的任何可排序标量表达式,例如 vector_cosine_similarityvector_l2_distancevector_inner_product或组合多个函数的复合表达式。

Syntax

{ INNER | LEFT [ OUTER ] } JOIN target_table_reference
  { APPROX | EXACT } NEAREST [ num_results ]
  BY { DISTANCE | SIMILARITY } ranking_expression

Parameters

  • target_table_reference

    要搜索的目标表。 可以是表、子查询或 CTE

  • { INNER | LEFT [ OUTER ] }

    Optional. 联接类型。 默认值为 INNER

    • INNER 删除没有匹配候选项的查询行。
    • LEFT OUTER 返回每个查询行。 目标端列是 NULL 不存在候选项时,例如,当目标表为空或每个候选项时 NULL。 如果查询行的候选项少于 num_results 候选项,则只返回可用的候选项。

    其他联接类型(RIGHT、、SEMIFULLANTICROSSNATURAL引发NEAREST_BY_JOIN.UNSUPPORTED_JOIN_TYPE

  • { APPROX | EXACT }

    控制结果集协定。

    • EXACT 返回下面确切的 top-k 行 ranking_expression
    • APPROX 返回一个 top-k 集,该集近似于确切排名。 优化器可以使用更快的近似搜索策略,而不是评估每个候选项。
  • NEAREST [ num_results ]

    可选的正整数文本。 默认值为 1. 必须位于范围内 [1, 100000]。 如果目标表的匹配行数少于 num_results,则只返回可用行。

    超出范围的值引发 NEAREST_BY_JOIN.NUM_RESULTS_OUT_OF_RANGE

  • 按距离 |相似

    设置 . 的 ranking_expression排序。

    • DISTANCE 先按最小值对行进行排名(最接近 = 最低距离)。
    • SIMILARITY 首先按最大值对行进行排名(最接近 = 最高相似性)。
  • ranking_expression

    一个标量表达式,可以引用这两个表中的列。

    常见选择包括:

    如果此表达式返回不支持排序的数据类型(如 MAP),Azure Databricks将引发 DATATYPE_MISMATCH。INVALID_ORDERING_TYPE

备注

非 对称

NEAREST BY 不是通勤的。 查询端定位结果 - 每个查询行最多生成 num_results 输出行:

  • 当表联接中的 users 100 行包含 1,000 行productsNEAREST 5时,联接将返回最多 500 行。
  • 如果将联接的两侧切换为联接productsusers,则最多返回 5,000 行。

交换双方提出不同的问题,因此结果甚至 INNER JOIN不同。

Streaming

NEAREST BY 流式处理数据帧或数据集不支持。 针对流式处理源的查询引发 NEAREST_BY_JOIN.STREAMING_NOT_SUPPORTED

嵌入输入

使用矢量评分函数时,这两个向量参数必须 ARRAY<FLOAT> 具有相同的维数。 有关类型和NULL处理规则,请参阅vector_cosine_similarity函数

若要从字符串值计算嵌入,请使用 ai_query 与 Databricks 托管的嵌入模型(例如 databricks-gte-large-en)。

常见错误条件

示例

以下示例使用这些表。 嵌入显示为简洁的三维向量;在实践中,它们是更高维的,由嵌入模型计算。

> CREATE TEMP VIEW users(user_id, name, embedding) AS
    VALUES
      (1, 'Alice', ARRAY(1.0f, 0.0f, 0.0f)),
      (2, 'Bob',   ARRAY(0.0f, 1.0f, 0.0f)),
      (3, 'Carol', ARRAY(0.0f, 0.0f, 0.0f));

> CREATE TEMP VIEW products(product_id, name, price, country, embedding) AS
    VALUES
      ('P1', 'Trail running shoes', 120, 'EU', ARRAY(0.9f, 0.1f, 0.1f)),
      ('P2', 'Hiking boots',        180, 'EU', ARRAY(0.8f, 0.2f, 0.0f)),
      ('P3', 'Office shoes',         95, 'US', ARRAY(0.1f, 0.9f, 0.1f)),
      ('P4', 'Sandals',              45, 'US', ARRAY(0.0f, 0.8f, 0.2f)),
      ('P5', 'Running shoes',       110, 'EU', ARRAY(0.5f, 0.5f, 0.0f));
-- Ad-hoc vector search with an explicit query vector.
> SELECT t.product_id, t.name
    FROM (SELECT ARRAY(1.0f, 0.0f, 0.0f) AS embedding) q
    INNER JOIN products t
      APPROX NEAREST 3 BY SIMILARITY vector_cosine_similarity(q.embedding, t.embedding);
 product_id  name
 ----------  -------------------
 P1          Trail running shoes
 P2          Hiking boots
 P5          Running shoes

-- Batch recommendations: for every user, return the 2 nearest products.
> SELECT q.user_id, q.name, t.product_id, t.name AS product
    FROM users q
    INNER JOIN products t
      APPROX NEAREST 2 BY SIMILARITY vector_cosine_similarity(q.embedding, t.embedding);
 user_id  name   product_id  product
 -------  -----  ----------  -------------------
 1        Alice  P1          Trail running shoes
 1        Alice  P2          Hiking boots
 2        Bob    P3          Office shoes
 2        Bob    P4          Sandals

-- Pre-filter the target table via a subquery (EU products only).
> SELECT q.user_id, q.name, t.product_id, t.name AS product, t.price
    FROM users q
    INNER JOIN (SELECT * FROM products WHERE country = 'EU') AS t
      APPROX NEAREST 2 BY SIMILARITY vector_cosine_similarity(q.embedding, t.embedding);
 user_id  name   product_id  product              price
 -------  -----  ----------  -------------------  -----
 1        Alice  P1          Trail running shoes  120
 1        Alice  P2          Hiking boots         180
 2        Bob    P5          Running shoes        110
 2        Bob    P2          Hiking boots         180

-- LEFT OUTER returns every query row. Carol's embedding has zero magnitude,
-- so vector_cosine_similarity returns NULL for all comparisons and her row
-- is preserved with NULL target columns.
> SELECT q.user_id, q.name, t.product_id, t.name AS product
    FROM users q
    LEFT OUTER JOIN products t
      APPROX NEAREST 2 BY SIMILARITY vector_cosine_similarity(q.embedding, t.embedding);
 user_id  name   product_id  product
 -------  -----  ----------  -------------------
 1        Alice  P1          Trail running shoes
 1        Alice  P2          Hiking boots
 2        Bob    P3          Office shoes
 2        Bob    P4          Sandals
 3        Carol  NULL        NULL

-- EXACT returns the exact top-k under the ranking expression.
> SELECT t.product_id, t.name
    FROM (SELECT ARRAY(1.0f, 0.0f, 0.0f) AS embedding) q
    INNER JOIN products t
      EXACT NEAREST 3 BY DISTANCE vector_l2_distance(q.embedding, t.embedding);
 product_id  name
 ----------  -------------------
 P1          Trail running shoes
 P2          Hiking boots
 P5          Running shoes