使用 RedisVL 进行复杂查询

一、前置条件

在开始之前,请确保:

  • 已安装 redisvl 并激活相应的 Python 环境。
  • 运行 Redis 实例,且 RediSearch 版本 > 2.4。

二、初始化与数据加载

我们将使用一个包含用户信息的数据集,字段包括 useragejobcredit_scoreoffice_locationuser_embeddinglast_updated。以下是初始化索引和加载数据的代码:

import pickle
from redisvl.index import SearchIndex# 加载示例数据
data = pickle.load(open("hybrid_example_data.pkl", "rb"))# 定义索引架构
schema = {"index": {"name": "user_queries","prefix": "user_queries_docs","storage_type": "hash",},"fields": [{"name": "user", "type": "tag"},{"name": "credit_score", "type": "tag"},{"name": "job", "type": "text"},{"name": "age", "type": "numeric"},{"name": "last_updated", "type": "numeric"},{"name": "office_location", "type": "geo"},{"name": "user_embedding","type": "vector","attrs": {"dims": 3,"distance_metric": "cosine","algorithm": "flat","datatype": "float32"}}],
}# 创建搜索索引
index = SearchIndex.from_dict(schema, redis_url="redis://localhost:6379")
index.create(overwrite=True)# 加载数据
keys = index.load(data)
print(index.info()['num_docs'])  # 输出:7

使用 rvl CLI 检查索引:

rvl index listall

三、混合查询

混合查询结合多种过滤器,例如根据年龄、职业和地理位置进行筛选。以下展示不同类型的过滤器及其应用。

3.1.标签过滤器(Tag Filters)

标签过滤器用于对分类字段(如 credit_score)进行精确匹配。

from redisvl.query import VectorQuery
from redisvl.query.filter import Tag# 筛选信用评分为 "high" 的用户
t = Tag("credit_score") == "high"
v = VectorQuery(vector=[0.1, 0.1, 0.5],vector_field_name="user_embedding",return_fields=["user", "credit_score", "age", "job", "office_location", "last_updated"],filter_expression=t
)
results = index.query(v)

输出:

vector_distance  user    credit_score  age  job            office_location      last_updated
0               john    high          18   engineer       -122.4194,37.7749    1741627789
0.109129190445  tyler   high          100  engineer       -122.0839,37.3861    1742232589
0.158808946609  tim     high          12   dermatologist  -122.0839,37.3861    1739644189
0.266666650772  nancy   high          94   doctor         -122.4194,37.7749    1710696589

支持否定和多值匹配:

# 否定:非 "high" 信用评分
t = Tag("credit_score") != "high"
v.set_filter(t)
results = index.query(v)
# 多值匹配:信用评分为 "high" 或 "medium"
t = Tag("credit_score") == ["high", "medium"]
v.set_filter(t)
results = index.query(v)

空标签列表会优雅地回退为通配符查询:

t = Tag("credit_score") == []
v.set_filter(t)
results = index.query(v)

3.2.数值过滤器(Numeric Filters)

数值过滤器用于筛选数值字段的范围或精确值。

from redisvl.query.filter import Num# 筛选年龄在 15-35 岁的用户
numeric_filter = Num("age").between(15, 35)
v.set_filter(numeric_filter)
results = index.query(v)

输出:

vector_distance  user    credit_score  age  job     office_location      last_updated
0               john    high          18   engineer  -122.4194,37.7749    1741627789
0.217882037163  taimur  low           15   CEO       -122.0839,37.3861    1742232589
0.653301358223  joe     medium        35   dentist   -122.0839,37.3861    1742232589

支持精确匹配和否定:

# 精确匹配:年龄为 14
numeric_filter = Num("age") == 14
v.set_filter(numeric_filter)
# 否定:年龄不为 14
numeric_filter = Num("age") != 14
v.set_filter(numeric_filter)

3.3.时间戳过滤器(Timestamp Filters)

时间戳过滤器支持使用 Python 的 datetime 对象进行时间筛选。

from redisvl.query.filter import Timestamp
from datetime import datetimedt = datetime(2025, 3, 16, 13, 45, 39, 132589)
timestamp_filter = Timestamp("last_updated") > dt
v.set_filter(timestamp_filter)
results = index.query(v)

输出:

vector_distance  user    credit_score  age  job       office_location      last_updated
0.109129190445  tyler   high          100  engineer  -122.0839,37.3861    1742232589
0.217882037163  taimur  low           15   CEO       -122.0839,37.3861    1742232589
0.653301358223  joe     medium        35   dentist   -122.0839,37.3861    1742232589

支持范围查询:

dt_1 = datetime(2025, 1, 14, 13, 45, 39, 132589)
dt_2 = datetime(2025, 3, 16, 13, 45, 39, 132589)
timestamp_filter = Timestamp("last_updated").between(dt_1, dt_2)
v.set_filter(timestamp_filter)

3.4.文本过滤器(Text Filters)

文本过滤器用于对文本字段进行精确、模糊或通配符匹配。

from redisvl.query.filter import Text# 精确匹配:职业为 "doctor"
text_filter = Text("job") == "doctor"
v.set_filter(text_filter)

输出:

vector_distance  user    credit_score  age  job     office_location      last_updated
0               derrick low           14   doctor  -122.4194,37.7749    1741627789
0.266666650772  nancy   high          94   doctor  -122.4194,37.7749    1710696589

支持通配符和模糊匹配:

# 通配符:职业以 "doct" 开头
wildcard_filter = Text("job") % "doct*"
v.set_filter(wildcard_filter)
# 模糊匹配:职业包含 "engine"
fuzzy_match = Text("job") % "%%engine%%"
v.set_filter(fuzzy_match)

支持条件匹配:

# 条件匹配:职业为 "engineer" 或 "doctor"
conditional = Text("job") % "engineer|doctor"
v.set_filter(conditional)

3.5.地理过滤器(Geo Filters)

地理过滤器用于筛选指定位置和半径范围内的记录。

from redisvl.query.filter import Geo, GeoRadius# 筛选距离旧金山办公室 10 公里内的用户
geo_filter = Geo("office_location") == GeoRadius(-122.4194, 37.7749, 10, "km")
v.set_filter(geo_filter)

输出:

score            vector_distance  user    credit_score  age  job            office_location
0.454545444693   0               john    high          18   engineer       -122.4194,37.7749
0.454545444693   0               derrick low           14   doctor         -122.4194,37.7749
0.454545444693   0.266666650772  nancy   high          94   doctor         -122.4194,37.7749

支持否定查询:

# 非 10 公里范围内的用户
geo_filter = Geo("office_location") != GeoRadius(-122.4194, 37.7749, 10, "km")
v.set_filter(geo_filter)

3.6.组合过滤器

通过 &(交集)和 |(并集)操作符组合多种过滤器。

t = Tag("credit_score") == "high"
low = Num("age") >= 18
high = Num("age") <= 100
ts = Timestamp("last_updated") > datetime(2025, 3, 16, 13, 45, 39, 132589)
combined = t & low & high & ts
v = VectorQuery([0.1, 0.1, 0.5],"user_embedding",return_fields=["user", "credit_score", "age", "job", "office_location"],filter_expression=combined
)
results = index.query(v)

输出:

vector_distance  user    credit_score  age  job       office_location
0.109129190445  tyler   high          100  engineer  -122.0839,37.3861

并集查询:

low = Num("age") < 18
high = Num("age") > 93
combined = low | high
v.set_filter(combined)

动态组合过滤器:

def make_filter(age=None, credit=None, job=None):flexible_filter = ((Num("age") > age) &(Tag("credit_score") == credit) &(Text("job") % job))return flexible_filter# 示例:筛选年龄 > 18,信用评分为 high,职业为 engineer
combined = make_filter(age=18, credit="high", job="engineer")
v.set_filter(combined)
results = index.query(v)

四、非向量查询

使用 FilterQuery 执行类似 SQL 的非向量查询:

from redisvl.query import FilterQueryhas_low_credit = Tag("credit_score") == "low"
filter_query = FilterQuery(return_fields=["user", "credit_score", "age", "job", "location"],filter_expression=has_low_credit
)
results = index.query(filter_query)

输出:

user    credit_score  age  job
derrick low           14   doctor
taimur  low           15   CEO

五、计数查询

使用 CountQuery 统计符合条件的记录数:

from redisvl.query import CountQueryhas_low_credit = Tag("credit_score") == "low"
filter_query = CountQuery(filter_expression=has_low_credit)
count = index.query(filter_query)
print(f"{count} records match the filter expression {str(has_low_credit)}")

输出:

4 records match the filter expression @credit_score:{low}

六、范围查询

RangeQuery 用于筛选向量距离在指定阈值内的记录:

from redisvl.query import RangeQueryrange_query = RangeQuery(vector=[0.1, 0.1, 0.5],vector_field_name="user_embedding",return_fields=["user", "credit_score", "age", "job", "location"],distance_threshold=0.2
)
results = index.query(range_query)

输出:

vector_distance  user    credit_score  age  job
0               john    high          18   engineer
0               derrick low           14   doctor
0.109129190445  tyler   high          100  engineer
0.158808946609  tim     high          12   dermatologist

调整距离阈值:

range_query.set_distance_threshold(0.1)
results = index.query(range_query)

结合过滤器:

is_engineer = Text("job") == "engineer"
range_query.set_filter(is_engineer)
results = index.query(range_query)

七、高级查询修饰符

支持排序、方言选择等高级功能:

v = VectorQuery(vector=[0.1, 0.1, 0.5],vector_field_name="user_embedding",return_fields=["user", "credit_score", "age", "job", "office_location"],num_results=5,filter_expression=is_engineer
).sort_by("age", asc=False).dialect(3)
results = index.query(v)

输出:

vector_distance  age  user    credit_score  job       office_location
0.109129190445  100  tyler   high          engineer  -122.0839,37.3861
0               18   john    high          engineer  -122.4194,37.7749

八、原始 Redis 查询字符串

将查询转换为原始 Redis 查询字符串:

str(v)

输出:

@job:("engineer")=>[KNN 5 @user_embedding $vector AS vector_distance] RETURN 6 user credit_score age job office_location vector_distance SORTBY age DESC DIALECT 3 LIMIT 0 5

直接使用原始查询字符串:

results = index.search("@credit_score:{high}")
for r in results.docs:print(r.__dict__)

九、清理

删除索引:

index.delete()

十、总结

RedisVL 提供了灵活的查询接口,支持标签、数值、时间戳、文本、地理等多种过滤器,以及向量、非向量、计数和范围查询。通过组合过滤器和动态参数化,开发者可以构建高效的搜索应用,适用于从简单到复杂的场景。更多查询修饰符和 API 详情,请参阅 RedisVL 官方文档。

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

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

相关文章

「Linux文件及目录管理」vi、vim编辑器

知识点解析 vi/vim编辑器简介 vi:Linux默认的文本编辑器,基于命令行操作,功能强大。vim:vi的增强版,支持语法高亮、多窗口编辑、插件扩展等功能。vi/vim基本模式 命令模式:默认模式,用于移动光标、复制、粘贴、删除等操作。插入模式:按i进入,用于输入文本。末行模式:…

电容器保护测控装置如何选型?

在电力系统的无功补偿环节&#xff0c;​电容器保护测控装置是保障并联电容器组安全稳定运行的核心设备。其选型需综合考量保护需求、系统环境及扩展功能。以下是关键选型要素分析&#xff1a; ​一、明确核心功能需求​ 电容器保护测控装置&#xff0c;选型时需匹配电容器组实…

最近小峰一直在忙国际化项目,确实有点分身乏术... [特殊字符] 不过! 我正紧锣密鼓准备一系列干货文章/深度解析

本人详解 大家晚上好呀&#xff01;&#x1f319; 最近小峰一直在忙国际化项目&#xff0c;确实有点分身乏术... &#x1f605; 不过&#xff01; 我正紧锣密鼓准备一系列干货文章/深度解析&#xff08;选一个更符合你内容的词&#xff09;&#xff0c;很快就会和大家见面啦&am…

OpenCV CUDA模块设备层-----设备端(GPU)线程块级别的一个内存拷贝工具函数blockCopy()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在同一个线程块&#xff08;thread block内&#xff0c;将 [beg, end) 范围内的数据并行地复制到 out 开始的位置。 它使用了 CUDA 线程协作机制…

https没有证书可以访问吗?外网怎么访问内网?

没有SSL证书的网站无法正常通过HTTPS协议访问‌。HTTPS的实现必须依赖有效的SSL证书完成加密握手&#xff0c;否则浏览器会直接阻断连接或显示严重的安全警告。‌‌ 一、技术实现层面‌ ‌HTTPS协议强制要求证书‌。 HTTPS基于SSL/TLS协议实现加密通信&#xff0c;而SSL证书是…

Python pytesseract【OCR引擎库】 简介

想全面了解DeepSeek的看过来 【包邮】DeepSeek全攻略 人人需要的AI通识课 零基础掌握DeepSeek的实用操作手册指南【限量作者亲笔签名版售完即止】 玩转DeepSeek这本就够了 【自营包邮】DeepSeek实战指南 deepseek从入门到精通实用操作指南现代科技科普读物AI普及知识读物人工智…

ubuntu安装postman教程并中文汉化详细教程

一、下载postman安装包 通过网盘分享的文件:Postman-linux-x64-8.7.0.tar.gz 链接: https://pan.baidu.com/s/10WYeguDJlK85cKJ6ptX01w?pwd=xqkh 提取码: xqkh 二、解压到/opt目录 tar -zxvf Postman-linux-x64-8.7.0.tar.gz如果子用户没有/opt权限,可以给子用户赋予/opt的…

《垒球知识科普》垒球世界纪录·垒球1号位

奥运垒球冠军记录 历届冠军榜 1996亚特兰大奥运会 冠军&#xff1a;美国队 ⚡ 首届奥运垒球赛&#xff0c;美国主场3战全胜夺冠&#xff01; 1996 Atlanta Olympics Champion: USA ⚡ Dominated all 3 games in first Olympic softball event 2000悉尼奥运会 冠军&#…

通信网络编程3.0——JAVA

主要添加了私聊功能 1服务器类定义与成员变量 public class ChatServer {int port 6666;// 定义服务器端口号为 6666ServerSocket ss;// 定义一个 ServerSocket 对象用于监听客户端连接//List<Socket> clientSockets new ArrayList<>();// 定义一个列表用于存储…

RediSearch `FT.CREATE` 完全参数指南 HASH/JSON 双写实战

1、索引与 Schema 速概 索引 (index) —— 倒排、前缀、向量、Geo … 元数据集合Schema —— 索引蓝图&#xff1a;定义字段、类型、权重、排序及存储策略FT.CREATE —— 创建索引命令&#xff0c;分「索引级参数」和「字段级参数」两层 2 、FT.CREATE 语法模板 FT.CREATE &…

QT学习教程(三十七)

系统繁忙时的响应&#xff08;Staying Responsive During Intensive Processing&#xff09; 当我们调用QApplication::exec()时&#xff0c;Qt 就开始了事件循环。启动时&#xff0c;Qt 发出显示和绘制事件&#xff0c;把控件显示出来。然后&#xff0c;事件循环就开始了&…

hot100 -- 17.技巧

1.多数元素 问题&#xff1a; 给定一个大小为 n 的数组 nums &#xff0c;返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。 你可以假设数组是非空的&#xff0c;并且给定的数组总是存在多数元素。 方法1&#xff1a; 哈希表 实时判断&#xff…

算法第39天| 打家劫舍 1、2、3

198. 打家劫舍 题目 思路与解法 class Solution { public:int rob(vector<int>& nums) {// dp数组含义&#xff1a;// 考虑下标i&#xff08;包括i&#xff09;以内的房屋&#xff0c;最多可以偷窃的金额为dp[i]if (nums.size() 0) return 0;if (nums.size() 1)…

车载CAN总线数据采集与故障诊断装置设计与实现

车载CAN总线数据采集与故障诊断装置设计与实现 链接:1.6W字 [下载]摘要1.1 研究背景1.2 研究意义(1)技术提升:推动CAN总线诊断的智能化与实时性(2)经济价值:降低诊断成本与维修时间(3)安全与标准化:促进车联网数据安全体系建设社会效益1.3 国内外研究现状1.3.1 国外研…

布瑞琳BRANEW:高端洗护领航者,铸就品质生活新典范

近日,布瑞琳BRANEW,这一中国高端洗护行业的领军品牌,再次凭借其卓越的服务品质、创新的经营模式以及对行业标准的深度推动,成为市场瞩目的焦点。作为北京2022年冬奥会和残奥会的商业服务保障单位,布瑞琳不仅展现了其无与伦比的服务能力,更在国际舞台上彰显了品牌的非凡影响力。…

AWS服务器扩充硬盘

1、在控制台上将需要扩充的硬盘增加空间 将硬盘大小由原来的50G升级到200G 2、登录所挂载的服务器 1&#xff09;查看硬盘分区情况 adminip-172-31-121-13:~$ sudo lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS nvme0n1 259:0 0 200G 0 disk ├─nv…

嵌入式自学第四十二天

PWM:脉冲宽度调制&#xff0c;调节电压为方波。关键参数&#xff1a;占空比、周期。 UART&#xff1a;通用异步收发器。 参与通信的设备&#xff1a;主机host 通信的本质&#xff1a;数据的传递。 通信方式&#xff1a; 单工&#xff1a;只能单向传递 半双工&#xff1a;双向…

人工智能如何重塑教育体系:个性化学习的新时代

&#x1f4dd;个人主页&#x1f339;&#xff1a;慌ZHANG-CSDN博客 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; 一、引言&#xff1a;教育的“智能革命”正在发生 教育作为人类社会发展的基石&#xff0c;始终紧随技术进步不断演化。从印刷术带来知识…

【云原生】基础篇

​一、云原生 1.1 本质与核心技术体系​ 云原生&#xff08;Cloud Native&#xff09;是以容器化、微服务、声明式API和动态编排为核心的架构范式&#xff0c;旨在最大化利用云的弹性、可观测性和自动化能力。其技术栈分层如下&#xff1a; ​1.2、云原生核心技术栈​ ​层级…

实时反欺诈:基于 Spring Boot 与 Flink 构建信用卡风控系统

在金融科技飞速发展的今天&#xff0c;信用卡欺诈手段日益高明和快速。传统的基于批处理的事后分析模式已难以应对实时性要求极高的欺诈场景。本文将详细介绍如何利用 Spring Boot 和 Apache Flink 这对强大的组合&#xff0c;构建一个高性能、可扩展的实时信用卡反欺诈系统。 …