【高速缓存】RedisVL 在 Redis 上使用 SQL 查询数据实践指南
Redis 本身并不原生支持 SQL但通过 RedisVL 提供的SQLQuery类你可以编写类似 SQL 的查询语句并自动翻译为 Redis 能够执行的底层命令。这不仅降低了学习曲线还能让你快速利用 Redis 的高级功能向量检索、地理空间、全文搜索等。本文将从零开始带你一步步掌握如何在 Redis 上使用 SQL 进行各种复杂查询并深入理解背后的工作原理。前置准备在开始之前请确保满足以下条件已安装 RedisVL 并启用 SQL 支持pipinstallredisvl[sql-redis]有一个正在运行的 Redis 实例建议 Redis 8 或使用 Redis Cloud且已安装 RediSearch 模块通常默认包含。概要使用SQLQuery编写 SQL 风格的查询语句将SELECT、WHERE、ORDER BY等子句翻译为 Redis 查询将 SQL 查询与向量搜索结合执行混合搜索使用聚合函数和分组GROUP BY使用geo_distance()查询地理数据使用YEAR()、MONTH()、DATE_FORMAT()等函数处理日期/时间整体工作流程下图展示了使用 SQLQuery 进行查询的完整流程定义 Schema创建样本数据创建 SearchIndex加载数据编写 SQL 查询执行查询获取结果查询类型条件查询文本搜索聚合查询向量搜索地理查询日期时间查询翻译为 FT.SEARCH / FT.AGGREGATE第一步定义 SchemaSchema模式定义了索引的结构包括字段名称、类型和属性。我们使用一个用户数据集包含用户信息、职位描述、地理位置和职位嵌入向量。fromredisvl.utils.vectorizeimportHFTextVectorizer# 使用 HuggingFace 的嵌入模型来生成文本向量hfHFTextVectorizer()schema{index:{name:user_simple,# 索引名称prefix:user_simple_docs,# 文档键前缀storage_type:json,# 存储类型JSON 或 Hash},fields:[{name:user,type:tag},# 标签字段可精确匹配{name:region,type:tag},{name:job,type:tag},{name:job_description,type:text},# 全文搜索字段{name:age,type:numeric},{name:office_location,type:geo},# 地理坐标{name:job_embedding,type:vector,attrs:{dims:len(hf.embed(get embed length)),# 向量维度distance_metric:cosine,# 余弦距离algorithm:flat,datatype:float32}}]}字段类型说明类型用途tag精确匹配如分类、枚举text全文搜索支持分词、模糊匹配numeric数值范围查询geo地理坐标经度,纬度vector向量嵌入用于相似性搜索第二步创建样本数据集我们准备一些模拟用户数据并为每个用户的职位描述生成向量嵌入。data[{user:john,age:34,job:software engineer,region:us-west,job_description:Designs, develops, and maintains software applications and systems.,office_location:-122.4194,37.7749# 旧金山},# ... 其他用户bill, mary, joe, stacy]# 生成向量将职位描述和职位名称拼接后嵌入data[{**d,job_embedding:hf.embed(f{d[job_description]}{d[job]}),}fordindata]注意地理坐标使用的是经度,纬度格式Redis 约定这与常见的地图坐标纬度在前相反务必牢记。第三步创建 SearchIndexSearchIndex是 RedisVL 中管理索引的核心类。你可以通过两种方式实例化方式一传入自定义 Redis 连接推荐用于生产环境fromredisvl.indeximportSearchIndexfromredisimportRedis clientRedis.from_url(redis://localhost:6379)indexSearchIndex.from_dict(schema,redis_clientclient)方式二让索引管理连接简单场景indexSearchIndex.from_dict(schema,redis_urlredis://localhost:6379)创建索引index.create(overwriteTrue,dropTrue)# 强制覆盖已有索引第四步加载数据将数据插入 Redis每个文档会以 JSON 格式存储根据 schema 中的storage_type。keysindex.load(data)# 返回每个文档的 keyprint(keys)验证提示RedisVL 默认使用 Pydantic 验证加载的数据是否符合 schema。但对于 GEO 字段由于格式约定经度在前验证可能暂不兼容我们在此忽略该选项未来版本会修正。第五步编写并执行 SQL 查询现在进入正题。我们使用SQLQuery类将 SQL 字符串转换为 Redis 命令字符串并执行。简单查询示例fromredisvl.queryimportSQLQuery sql_str SELECT user, region, job, age FROM user_simple WHERE age 17 sql_querySQLQuery(sql_str,sql_redis_options{schema_cache_strategy:lazy})sql_redis_options可配置缓存策略lazy默认按需加载 schema适合首次查询较慢但后续快速的场景load_all启动时预加载所有 schema适合频繁查询多样表的场景查看生成的 Redis 命令redis_querysql_query.redis_query_string(redis_urlredis://localhost:6379)print(redis_query)# 输出FT.SEARCH user_simple age:[(17 inf] RETURN 4 user region job age DIALECT 2执行查询resultsindex.query(sql_query)print(results)可以看到返回了所有年龄大于 17 的用户。查询类型详解1. 条件运算符AND、OR、INAND 条件SELECTuser,region,job,ageFROMuser_simpleWHEREage17ANDregionus-west翻译后的 Redis 命令会在age和region之间进行交集AND。OR 条件WHEREregionus-westORregionus-central翻译为((region:{us\-west})|(region:{us\-central}))使用并集。IN 运算符仅对 tag 字段WHEREjobIN(software engineer,engineer,pancake tester)翻译为job:{software engineer|engineer|pancake tester}。2. 文本搜索文本字段text支持多种匹配模式操作符说明SQL 示例Redis 翻译精确短语匹配自动去停用词WHERE job_description healthcare includingjob_description:healthcare includingLIKE sci%前缀匹配WHERE job_description LIKE sci%job_description:sci*LIKE %care后缀匹配WHERE job_description LIKE %carejob_description:*careLIKE %diagnose%包含匹配WHERE job_description LIKE %diagnose%job_description:*diagnose*fuzzy(column, ...)容错匹配允许拼写错误WHERE fuzzy(job_description, diagnose)使用%和~实现模糊搜索fulltext(column, ...)分词搜索支持布尔操作WHERE fulltext(job_description, healthcare OR diagnosing)标准全文搜索原理Redis 的FT.SEARCH支持通配符*和~实现模糊fulltext则是基于分词和倒排索引。3. 聚合查询GROUP BY 聚合函数聚合查询使用FT.AGGREGATE命令。支持以下聚合函数COUNT、COUNT_DISTINCTMIN、MAX、AVG、STDEVFIRST_VALUE、LAST_VALUEARRAY_AGG收集为列表QUANTILE(column, p)百分位数示例SELECTregion,COUNT(age)ascount_age,AVG(age)asavg_age,QUANTILE(age,0.99)asquantile_ageFROMuser_simpleGROUPBYregion这将按区域分组计算统计量。对应的 Redis 命令会生成GROUPBY和多个REDUCE子句。4. 向量搜索相似性检索使用cosine_distance()函数计算向量相似度并可按距离排序。SELECTuser,job,cosine_distance(job_embedding,:vec)ASvector_distanceFROMuser_simpleORDERBYvector_distanceASC这里:vec是参数占位符执行时需传入实际的向量二进制格式。Redis 会执行 KNN 搜索默认返回前 10 个结果。参数传递vechf.embed(looking for someone to use base principles to solve problems,as_bufferTrue)sql_querySQLQuery(sql_str,params{vec:vec})翻译后的命令使用*[KNN 10 job_embedding $vector AS vector_distance]。混合搜索Hybrid Search从 Redis 8.4 开始支持FT.HYBRID将全文搜索和向量搜索的结果融合排序。使用hybrid_vector_search()函数SELECTuser,job,job_description,hybrid_vector_search(cosine_distance(job_embedding,:vec),fulltext(job_description,principles solve problems),rrf()-- 或 linear())AShybrid_scoreFROMuser_simpleORDERBYhybrid_scoreDESCrrf()倒数排名融合平衡文本和向量权重linear()线性加权可指定权重这与预过滤在 WHERE 中加条件不同——混合搜索是两个独立的排序再融合而预过滤是在向量搜索前先限定文档集合。5. 地理查询GeospatialRedis 支持地理空间索引使用geo_distance()函数进行距离过滤或计算。过滤在 WHERE 中使用SELECTuser,job,regionFROMuser_simpleWHEREgeo_distance(office_location,POINT(-122.4194,37.7749),km)500POINT(lon, lat)经度在前纬度在后与 Redis 一致单位km、mi、m、ft翻译后生成GEOFILTER office_location -122.4194 37.7749 500.0 km。距离计算在 SELECT 中SELECTuser,geo_distance(office_location,POINT(-73.9857,40.7580))ASdistance_metersFROMuser_simple结果返回距离单位米。这里geo_distance不带单位参数默认返回米。结合其他条件可结合标签、数值、文本条件WHEREjobengineerANDgeo_distance(...)50这会在GEOFILTER之前加上job:{engineer}过滤。地理查询总结用法SQL 示例距离过滤WHERE geo_distance(field, POINT(lon, lat), km) radius距离计算SELECT geo_distance(field, POINT(lon, lat)) AS dist组合过滤WHERE age 30 AND geo_distance(...) 100多条件使用 AND/OR 与 TAG、NUMERIC 等组合6. 日期和时间查询Redis 使用 Unix 时间戳整数存储日期因此日期字段类型为numeric。RedisVL 支持日期字面量和日期函数。日期字面量WHEREcreated_at2024-01-012024-01-01会被自动转换为 Unix 时间戳1704067200。日期范围WHEREcreated_atBETWEEN2024-01-01AND2024-03-31日期函数YEAR(created_at)提取年份MONTH(created_at)提取月份返回 0~110 表示一月DATE_FORMAT(created_at, %Y-%m-%d)格式化为字符串SELECTname,YEAR(created_at)ASyear,MONTH(created_at)ASmonthFROMevents按日期分组SELECTYEAR(created_at)ASyear,COUNT(*)ASevent_countFROMeventsGROUPBYyear重要提示存储日期必须存储为整数时间戳如int(datetime.timestamp())时区日期字面量默认视为 UTCMONTH 返回 0~11与常见习惯不同需注意原生过滤器Native Filters除了 SQL 语法RedisVL 还提供了编程式的过滤器类可用于构建更复杂的组合条件尤其适合动态构建查询。fromredisvl.queryimportFilterQueryfromredisvl.query.filterimportGeo,GeoRadius,Tag,Num# 地理过滤器geo_filterGeo(office_location)GeoRadius(-87.6298,41.8781,100,km)# 标签过滤器job_filterTag(job)engineer# 数值过滤器age_filterNum(age)40combinedgeo_filterjob_filterage_filter queryFilterQuery(filter_expressioncombined,return_fields[user,job,age])resultsindex.query(query)这种方式更接近 Redis 原生语法适合在代码中灵活组合条件。异步支持如果你的应用是异步的如使用 FastAPIRedisVL 提供了AsyncSearchIndexfromredisvl.indeximportAsyncSearchIndexfromredisvl.queryimportSQLQuery async_indexAsyncSearchIndex.from_dict(schema,redis_urlredis://localhost:6379)sql_querySQLQuery(SELECT user, age FROM user_simple WHERE age 30)resultsawaitasync_index.query(sql_query)awaitasync_index.disconnect()异步版本与同步版本 API 一致仅执行方法为await。清理资源完成操作后可以删除索引以释放资源index.delete()结语通过SQLQuery你可以用熟悉的 SQL 语法操控 Redis 的强大功能而无需记忆复杂的 Redis 命令。本文涵盖了从安装、建表到各类查询的完整流程并深入解释了每个环节的底层原理。RedisVL 的 SQL 支持并非完全的 SQL 实现而是针对 Redis 特点的精心封装使得开发体验大大提升。尝试结合你的业务场景探索更多可能。

相关新闻

【高速缓存】RedisVL为文本生成嵌入向量实践指南

【高速缓存】RedisVL为文本生成嵌入向量实践指南

在现代语义搜索和 RAG 应用中,文本嵌入(Embedding) 是核心基础——它将自然语言转换成高维数值向量,使得计算机能够“理解”语义相似性。RedisVL 提供了一套统一的向量化器接口,让你可以使用多种主流嵌入服务&#xff…

2026/10/14 4:28:11 阅读更多 →
ADS131A0x高精度ADC实战:从硬件设计到固件驱动的电能计量系统指南

ADS131A0x高精度ADC实战:从硬件设计到固件驱动的电能计量系统指南

1. 项目概述:从芯片手册到高精度数据采集实战如果你正在为电能计量、电网保护或者高精度多通道数据采集系统选型,那么德州仪器(TI)的ADS131A02和ADS131A04这两颗24位同步采样Δ-Σ ADC,大概率已经进入了你的视野。它们…

2026/10/14 4:27:18 阅读更多 →
为什么你的英文Prompt总被误读?揭秘中文提示词翻译中隐藏的4层语义损耗机制

为什么你的英文Prompt总被误读?揭秘中文提示词翻译中隐藏的4层语义损耗机制

更多请点击: https://codechina.net 第一章:为什么你的英文Prompt总被误读?揭秘中文提示词翻译中隐藏的4层语义损耗机制 当你将“Generate a concise, professional email summarizing the Q3 sales report with bullet points and a call-t…

2026/10/4 1:28:20 阅读更多 →

最新新闻

燃烧仿真中辐射传热模型怎么选?DO与WSGGM实战指南

燃烧仿真中辐射传热模型怎么选?DO与WSGGM实战指南

1. 辐射传热:燃烧仿真中最容易忽略的主角做燃烧仿真的人都知道一个矛盾:大多数人入门的第一个燃烧算例,火焰温度总是偏高。不管湍流模型怎么调、化学反应机理怎么换,炉膛出口温度就是压不下来。直到某天某位前辈淡淡说了一句“你开…

2026/10/14 4:27:51 阅读更多 →
GridView AJAX化实战:告别Postback,实现无刷新分页与排序

GridView AJAX化实战:告别Postback,实现无刷新分页与排序

简介:面向ASP.NET开发者的GridView实用示例包,针对VS自带的GridView在数据增删改操作上不灵活、页面刷新频繁、交互体验差等痛点,提供了一套基于ASP.NET 4.0与SQL Server 2008的轻量级解决方案,通过Ajax实现无刷新操作&#xff0c…

2026/10/14 4:27:51 阅读更多 →
什么情况下索引会失效

什么情况下索引会失效

一、什么叫做索引失效索引失效,是指查询时因为写法或条件的问题,数据库用不上(或只用上一部分)已有的索引,导致加速能力丧失,退化成全表扫描或逐行过滤。数据照样查得出来,结果也对,…

2026/10/14 4:27:51 阅读更多 →
数据中心废热回收:从能源黑洞到热源工厂的工程实践

数据中心废热回收:从能源黑洞到热源工厂的工程实践

数据中心在多数人的第一印象里就是“电老虎”“能源黑洞”,这个印象不算错,但往往忽略了一件关键的事:电力穿过服务器之后,并没有真的消失,而是变成了热量。只是这些热量通常被冷却塔、风机和冷冻水系统当作废料排进大…

2026/10/14 4:27:51 阅读更多 →
2025年12月六级真题三套全解析:考点拆解与复盘方法

2025年12月六级真题三套全解析:考点拆解与复盘方法

2025年12月的大学英语六级考试一结束,我就开始整理这一批真题。原因很简单:备考群里连续好几天都有人在问卷子做得对不对、作文跑没跑题、三套卷到底该先做哪套。我把三套题目重新过了一遍,也把答案解析重新盘了一遍,这篇就从这套…

2026/10/14 4:27:51 阅读更多 →
AnyPS5跨平台图像处理管线:色彩管理与批量处理实战避坑指南

AnyPS5跨平台图像处理管线:色彩管理与批量处理实战避坑指南

1. 项目缘起与核心定位AnyPS5 这个名字第一次出现在我视野里的时候,我正被一堆跨平台图像处理的需求折腾得够呛。团队里有人用 Windows 做设计,有人用 macOS 做后期,还有几个同事习惯在 Linux 环境下跑批处理脚本,每次交付素材都要…

2026/10/14 4:26:51 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →