【高速缓存】RedisVL 在 Redis 上使用 SQL 查询数据实践指南

发布时间:2026/9/12 16:51:09

【高速缓存】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 特点的精心封装使得开发体验大大提升。尝试结合你的业务场景探索更多可能。
延伸阅读

更多相关文章

2026/9/12 16:51:08

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

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

2026/9/9 14:37:16

FigmaCN中文翻译插件终极指南:3分钟让你的Figma界面全中文化

FigmaCN中文翻译插件终极指南:3分钟让你的Figma界面全中文化 【免费下载链接】figmaCN 中文 Figma 插件,设计师人工翻译校验 项目地址: https://gitcode.com/gh_mirrors/fi/figmaCN 还在为Figma的全英文界面而头疼吗?菜单看不懂、工具…

2026/9/12 16:50:53

2026年学术论文降AI工具评测与最佳实践指南

1. 项目背景与核心需求 2026年的学术环境正在经历一场前所未有的变革。随着AI生成内容的普及,学术诚信面临全新挑战。各大高校和期刊编辑部纷纷引入AI检测工具,导致大量论文因"AI率过高"被退回或质疑。在这个背景下,论文降AI工具应…

2026/9/12 16:50:53

用一句自然语言让浏览器替你干活:MidScene.js 上手记

用一句自然语言让浏览器替你干活:MidScene.js 上手记 【免费下载链接】midscene GUI Agent for E2E Testing 项目地址: https://gitcode.com/GitHub_Trending/mid/midscene MidScene.js 是一款 AI 浏览器自动化工具,你用中文或英文写一句话&#…

2026/9/12 16:45:53

环境变量与密钥管理实战:彻底告别硬编码密码

前阵子接手一个外包项目的交接,代码拉到本地,随手翻到config.js里面静静躺着一段password: "Pssw0rd2022"。我当场截图发到工作群,问这是谁的,群里安静了十分钟,最后有人在私聊里回了一句"先跑起来再说…

2026/9/12 2:05:33

超人会飞不算本事:系统稳定依赖清晰规则与边界设计

开头先不绕弯子。“#斯坦李吐槽dc 所以超人是无缘无故会飞的嘛哈哈哈哈哈哈哈锤哥真是技术人才啊!#雷神 #复联”这类调侃式短标题,第一波冲击力在于它把两个宇宙的角色塞进同一个吐槽箱里,但细想一下就能发现,它真正碰到的根本不是…

2026/9/12 3:55:12

超人VS蜘蛛侠:拆解超级IP的影响力与传播方法论

把“蜘蛛侠 vs 超人”放在 CSDN 上聊,可能很多人第一反应是走错片场了。但如果把这两个角色看成“两个持续运营了 80 多年的文化产品”,你会发现,这场比较本质上是两个不同 IP 策略的长期结果对比:超人赢在定义了整个超级英雄题材…

2026/9/12 10:09:03

基于CNN的调制信号识别:MATLAB实现时频图分类实战

简介:本资源是一套面向通信工程与信号处理方向学习者、研究者的深度学习实践方案,聚焦调制信号自动检测与识别这一典型无线通信任务,解决传统方法依赖人工特征、低信噪比下性能下降等痛点。压缩包共12个文件(10.73MB)&…

2026/9/12 0:04:17

MATLAB仿生优化框架:长鼻浣熊算法多策略融合实现

简介:本资源是一份面向智能优化算法研究者与MATLAB初学者的仿生智能算法实践代码包,聚焦于长鼻浣熊优化算法(COA)的多策略改进与性能验证。针对传统COA易陷局部最优、收敛精度不足等问题,作者融合Circle映射初始化提升…

2026/9/12 0:04:17

【JAVA毕设源码分享】基于 JavaWeb 的校园一卡通管理系统的设计与实现 基于 JavaWeb 的校园卡业务管理系统(程序+文档+代码讲解+一条龙定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/9/12 0:04:17

【JAVA毕设源码分享】基于 Java 的图书馆借阅管理平台的搭建与实现 基于 Java 的图书馆综合管理系统(程序+文档+代码讲解+一条龙定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/9/12 6:29:36

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/12 14:32:17

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/12 6:37:43

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码