在 Flink SQL 里做向量检索 VECTOR_SEARCH - 教程

news/2026/1/9 21:01:16/文章来源:https://www.cnblogs.com/gccbuaa/p/19446962

1. 背景:为什么要在 Flink 里做向量搜索?

大模型和向量数据库火起来之后,向量检索基本成了各种智能应用的标配:

  • RAG(检索增强生成):用文本向量找最相关的文档片段;
  • 推荐 / 相似内容:根据用户向量找相似用户,或者根据物料向量找相似物料;
  • 画像 / embedding 检索:根据用户行为 embedding 找“最近邻”人群做实时推荐。

典型架构一般是:

  1. Flink / 各种 ETL 把数据加工成特征;
  2. 把文本或特征喂给 embedding 模型生成向量;
  3. 把向量写入向量数据库(如 Milvus、pgvector、ES / OpenSearch vector 字段等);
  4. 查询阶段,应用服务拿到查询向量,调用向量库 API 获取 Top-K,再走后续逻辑。

这套架构有两个痛点:

  • 实时性不好控制:实时流进 Flink,结果还要绕一圈到应用层才能做向量检索;
  • 逻辑分裂:特征加工在 Flink,向量检索在服务层,SQL/代码分散在不同系统中。

Flink 提供的 VECTOR_SEARCH 表值函数,就是把这件事整合回 SQL 世界:

让你直接在 Flink SQL 查询里写:
FROM input_table, LATERAL TABLE(VECTOR_SEARCH(...))
一边在流上加工数据,一边实时查向量库,拿到 Top-K 相似结果和 score。

这对实时推荐、实时 RAG Pipeline、相似告警合并等场景非常友好。

2. VECTOR_SEARCH 是什么?和 lookup join 有什么关系?

直观理解:

  • 它长得很像一个 特殊的 lookup join

  • 只不过匹配条件不是 ON a.key = b.key,而是:

    用输入行的向量和外部表里的向量算相似度,然后返回 Top-K 行。

在 SQL 里,它是一个 表值函数(TVF),通常和 LATERAL TABLE 一起使用:

FROM input_table,
LATERAL TABLE(VECTOR_SEARCH(...))

语义上相当于:

  • input_table 中的每一行拿到一个向量 v_in
  • vector_table 中按某一列 index_column 做相似度检索;
  • 返回 Top-K 相似行以及相似度 score
  • 再把这些行与原始行拼成一张“展开的”结果表。

3. 语法拆解:每一块到底干什么?

完整写法:

SELECT *
FROM input_table,
LATERAL TABLE(
VECTOR_SEARCH(
TABLE vector_table,
input_table.vector_column,
DESCRIPTOR(index_column),
top_k,
[CONFIG => MAP['key', 'value']]
)
);
3.1 input_table:查询“驱动表”
  • 是流式输入:比如实时行为流、实时日志流;
  • 每一条记录中会包含一个向量列 vector_column,或者可以先在 SQL 里把 embedding 拼成数组。
3.2 vector_table:向量索引所在的外部表
3.3 input_table.vector_column:要用来检索的向量
  • 类型必须是 FLOAT ARRAYDOUBLE ARRAY

  • 你可以:

    • 直接从上游数据里拿 embedding;
    • 或者在 Flink SQL 里通过 UDF + 特征拼接成向量列。

举例:

-- 假设 user_embedding 是 FLOAT ARRAY
input_table.user_embedding
3.4 DESCRIPTOR(index_column):向量表里的索引列
  • 指定 vector_table 中哪一列是用来做相似度搜索的向量列;
  • 一般会是向量数据库中的 embedding 列。
DESCRIPTOR(embedding)  -- vector_table.embedding
3.5 top_k:返回多少个最近邻
  • 经典向量检索参数;
  • 对每条输入记录,会返回 Top-K 相似行;
  • 注意:结果表会“变宽也变高”,一条输入行可能展开成 K 条结果。
3.6 CONFIG:异步搜索配置

ML_PREDICT 一样,异步配置也有这些:

示例:

MAP[
'async', 'true',
'max-concurrent-operations', '2000',
'output-mode', 'ALLOW_UNORDERED',
'timeout', '3s'
]

4. 典型使用示例

4.1 基础用法:实时查询相似物料

假设:

-- user_stream: 实时用户行为 + embedding
CREATE TABLE user_stream (
user_id     STRING,
action      STRING,
emb         FLOAT ARRAY,
ts          TIMESTAMP_LTZ(3),
WATERMARK FOR ts AS ts - INTERVAL '5' SECOND
) WITH (...);
-- item_vectors: 商品向量外部表
CREATE TABLE item_vectors (
item_id     STRING,
title       STRING,
desc        STRING,
emb         FLOAT ARRAY
) WITH (...); -- 实现了 VectorSearchTableSource 的 Connector
-- 实时查找 Top-10 相似商品
SELECT
u.user_id,
u.action,
i.item_id,
i.title,
v.score      -- 相似度
FROM user_stream AS u,
LATERAL TABLE(VECTOR_SEARCH(
TABLE item_vectors,
u.emb,                      -- 输入向量
DESCRIPTOR(emb),            -- 索引列
10                          -- top_k
)) AS v                        -- v 中包含 item_vectors 的列和 score
JOIN item_vectors AS i ON v.item_id = i.item_id;   -- 或直接从 v 中取

实际上 VECTOR_SEARCH(...) 的输出已经包含 item_vectors 的列,你可以不再单独 join 一次,这里只是形式上写清楚。

4.2 带异步配置的实时向量检索
SELECT
u.user_id,
i.item_id,
i.title,
v.score
FROM user_stream AS u,
LATERAL TABLE(VECTOR_SEARCH(
TABLE item_vectors,
u.emb,
DESCRIPTOR(emb),
10,
MAP[
'async', 'true',
'max-concurrent-operations', '2000',
'output-mode', 'ALLOW_UNORDERED',
'timeout', '2s'
]
)) AS v
JOIN item_vectors AS i ON v.item_id = i.item_id;
4.3 用常量向量直接搜索(不需要 LATERAL)

当查询向量是常量 / 字面量时,不需要 LATERAL

SELECT *
FROM TABLE(VECTOR_SEARCH(
TABLE item_vectors,
ARRAY[0.12, 0.35, -0.11, ...],  -- 常量向量
DESCRIPTOR(emb),
5
));

这在做 一次性分析 / 调试 embedding 时很方便。

5. 输出结构与相似度 score

VECTOR_SEARCH 的输出表包含:

  1. 输入表 input_table 的所有列;
  2. 向量表 vector_table 的所有列;
  3. 一个额外的 score 列。

你可以把它当成一种特殊 join 的结果,只不过 join 条件变成了“按相似度 Top-K”。

score 的具体含义(内积、余弦相似度、L2 距离的负数等)由底层向量引擎决定,通常:

  • 越大代表越相似(比如内积 / 余弦相似度);
  • 或者越小越相似(L2 距离),此时 connector 可以做适配,转成“相似度分数”。

无论如何,在 SQL 里你可以对 score 再做二次处理:

  • 过滤低于阈值的结果;
  • 对同一 user / 查询向量做二次排序等。

6. 限制与实现要求

6.1 只支持 append-only 表

文档里和 ML_PREDICT 一样强调:

VECTOR_SEARCH 只支持消费追加表(append-only tables)。

原因类似:向量检索通常依赖外部索引结构,变更行(update / delete)会让语义变得很复杂,并且向量库本身的更新语义一般是异步 eventually consistent

6.2 Connector 必须实现 VectorSearchTableSource

向量表 vector_table 背后的 Source 必须实现:

这个接口定义了 Flink 如何向外部向量服务发起检索请求、如何接收 Top-K 结果。
你在 SQL 这一侧不用关心实现细节,只需要知道:

7. 性能调优和实践建议

要让 VECTOR_SEARCH 在生产环境里跑得又稳又快,可以关注这几个点:

  1. 优先使用异步模式(async = true)

    • 向量检索基本都是网络调用 + 索引扫描,单次延迟普遍较高;
    • 异步模式可以“挂起”很多并发请求,把网络延迟藏在算子内部。
  2. 合理设置 max-concurrent-operations

    • 太小:并发不足,CPU/网络都吃不满;
    • 太大:向量库会被打爆,或者 Flink 任务本身内存 / 连接资源吃紧;
    • 一般可以按:(期望QPS * 远端平均延迟) 做一个量级估算,再慢慢调优。
  3. 视业务情况选择 ORDERED / ALLOW_UNORDERED

    • 多数“Top-K 相似结果”的业务对“结果顺序 = 输入顺序”没有强依赖,可以用 ALLOW_UNORDERED 换一点性能;
    • 如果你需要保证“对每条输入记录,返回结果必须严格按输入顺序输出”,就用默认 ORDERED
  4. 在 Flink 内完成尽可能多的特征/向量预处理

    • 比如先在 SQL 里把多字段拼成一个向量,再调用 VECTOR_SEARCH
    • 这样向量库只负责检索,而不是做额外的 feature 工程。

8. 小结

VECTOR_SEARCH 把“向量检索”这件事变成了 Flink SQL 里的一个普通 TVF:

一句话总结:

以前要写一堆服务代码调用向量库,现在可以在 Flink SQL 里一句
..., LATERAL TABLE(VECTOR_SEARCH(...)) 搞定。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1118292.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

详细介绍:(12)功能实现:Qt实战项目之读写配置文件

详细介绍:(12)功能实现:Qt实战项目之读写配置文件pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas&qu…

LeetCode 面试经典 150_二分查找_搜索插入位置(111_35_C++_简单)

LeetCode 面试经典 150_二分查找_搜索插入位置(111_35_C_简单)题目描述:输入输出样例:题解:解题思路:思路一(二分查找):代码实现代码实现(思路一(…

2026年政务大厅智能化建设必备设备与硬件清单解析 - 智造出海

随着政务服务智能化渗透率要求的不断提升,传统政务大厅在高峰期分流、跨部门业务协同及适老化服务方面仍面临显著挑战。硬件设施的数字化升级是突破服务效率瓶颈、实现“一网通办”线下落地的基础保障,以下是对政务场…

2026年汽车4S店数字化转型必备智能设备全解析 - 智造出海

当前汽车零售行业面临人力成本攀升与服务体验同质化的双重挑战,传统的人海战术已难以适应精细化运营需求。通过引入智能化硬件设备重构“接待-销售-售后”全链路,成为提升门店运营效率与客户转化率的关键路径。以下是…

Zookeeper分布式锁实现原理讲解:配合代码片段逐步演示

Zookeeper分布式锁实现原理讲解:配合代码片段逐步演示 在构建高可用的分布式系统时,一个常见的挑战是:如何让多个服务实例安全地协调对共享资源的访问?设想这样一个场景——你部署了三个微服务实例来执行每天凌晨的数据报表生成任…

网盘直链下载助手背后的秘密:如何用VibeThinker生成Python下载脚本

网盘直链下载助手背后的秘密:如何用VibeThinker生成Python下载脚本 在日常开发中,你是否曾为批量下载网盘文件而烦恼?官方客户端限速、无法断点续传、缺乏进度反馈——这些问题早已成为开发者心中的“痛点”。但有没有可能,我们不…

离散数学(1) | 6 | 谓词逻辑的基本概念

文章同步于@c.w.-知乎,个人博客本文及其系列文章用于离散数学(1)科目的期末考试复习 一些定义和名称个体词就是命题逻辑里面的主词。包括了个体常项和个体变项。将个体变化的范围成为个体域或者论域\(D\)。谓词指的…

Swagger UI展示API接口:便于开发者快速接入

Swagger UI展示API接口:便于开发者快速接入 在人工智能模型日益普及的今天,如何让一个训练好的模型真正“用起来”,而不是锁在实验环境中,成为许多团队面临的关键挑战。尤其是对于像 VibeThinker-1.5B-APP 这样专注于数学推理与编…

GEO优化公司如何选择?2026年北京市场5家实力服务商对比与推荐 - 十大品牌推荐

在生成式人工智能(AI)深度重塑信息分发与获取范式的当下,企业品牌在AI对话答案中的“可见性”与“权威性”已取代传统搜索引擎排名,成为决定商业增长潜力的全新战略制高点。生成式引擎优化(GEO)应运而生,正从一…

揭秘Docker镜像标签混乱难题:3步构建清晰、可追溯的标签体系

第一章:揭秘Docker镜像标签混乱的根源Docker镜像标签(Tag)是标识镜像版本的重要机制,但实际使用中常出现标签滥用、覆盖和歧义等问题,导致部署不稳定与环境不一致。标签并非不可变的版本号,而是可被重新指向…

从零开始部署VibeThinker-1.5B-APP:Jupyter+Shell脚本快速启动教程

从零开始部署VibeThinker-1.5B-APP:JupyterShell脚本快速启动教程 在算法竞赛训练营里,一个学生正盯着LeetCode上的“两数之和”题目发愁。他没有翻题解,而是打开了本地AI推理界面,输入:“You are a programming assis…

Docker容器部署失控后果有多严重(真实案例曝光)

第一章:Docker容器部署失控的现实威胁在现代云原生架构中,Docker容器因其轻量、可移植和快速启动的特性被广泛采用。然而,缺乏规范管理的容器部署正成为企业IT安全与稳定的重大隐患。当开发团队随意创建、运行和共享容器镜像时,极…

如何实现零停机部署?Docker Compose + Nginx热加载配置实战(稀缺方案曝光)

第一章:零停机部署的核心概念与架构设计零停机部署(Zero-Downtime Deployment)是一种确保应用在更新过程中持续对外提供服务的技术策略。其核心目标是在发布新版本时,避免用户访问中断或请求失败,从而提升系统的可用性…

发票开具申请:企业用户购买后的财务支持

VibeThinker-1.5B-APP:轻量模型如何实现高阶推理突破 在大模型军备竞赛愈演愈烈的今天,动辄千亿参数、百万美元训练成本的“巨无霸”模型似乎成了行业标配。然而,当企业真正将这些庞然大物投入生产环境时,高昂的部署开销和复杂的运…

HTML页面自动生成器?用VibeThinker解析需求并输出结构化代码

VibeThinker:用15亿参数的小模型生成专业级HTML页面 在前端开发的世界里,一个常见的痛点是——明明只是想快速搭个作品集页面,却不得不反复翻查文档、调试CSS布局。有没有可能,我们只需一句话:“做个响应式网页&#x…

Falco日志分析进阶之路:从入门规则到自定义检测策略(附实战案例)

第一章:Falco日志分析的核心价值与应用场景Falco 是一个开源的云原生运行时安全工具,专注于实时检测异常行为和潜在威胁。它通过监听系统调用和容器事件,结合可定制的规则引擎,能够精准识别不符合预期的行为模式,为 Ku…

Kibana可视化分析:洞察用户使用行为模式

VibeThinker-1.5B:小模型如何实现高效推理突破 在AI大模型军备竞赛愈演愈烈的今天,动辄数百亿甚至万亿参数的“巨无霸”似乎成了主流。然而,当算力成本高企、部署门槛居高不下时,一个反向趋势正在悄然兴起——用更少的参数&#x…

信泰楼文具市场口碑怎么样?信泰楼马克笔质量评价及年度文具定制企业推荐 - 工业品网

本榜单依托全维度市场调研与真实行业口碑,深度筛选出五家标杆文具企业,重点围绕信泰楼系列产品口碑、品牌实力及定制服务能力展开分析,为企业选型提供客观依据,助力精准匹配适配的服务伙伴。 TOP1 推荐:汕头市新…

MongoDB存储历史记录:结构化保存问答对

MongoDB 存储历史记录:结构化保存问答对 在 AI 模型日益深入实际业务的今天,一个常被忽视却至关重要的问题浮出水面:我们如何记住模型“思考”过什么? 尤其是在数学证明、算法推导这类需要多步逻辑链的任务中,每一次推…

Git commit规范难统一?AI模型帮你自动生成专业提交信息

Git Commit 规范难统一?让 AI 帮你生成专业提交信息 在现代软件开发中,一个看似微不足道的环节——写 Git 提交信息,却常常成为团队协作中的“隐形瓶颈”。我们都有过这样的经历:改完代码,git add . 之后愣住&#xf…