Redis模块支持:JSON、搜索与时间序列数据处理
【免费下载链接】redis-py Redis Python Client 项目地址: https://gitcode.com/GitHub_Trending/re/redis-py
本文详细介绍了Redis通过模块扩展提供的三大核心功能:RedisJSON模块的JSON文档操作与数据序列化、RediSearch模块的全文搜索功能集成、以及RedisTimeSeries模块的时间序列数据分析。文章通过丰富的Python代码示例,展示了如何使用redis-py客户端进行JSON数据的基本操作、高级查询、数组和对象操作;如何构建全文搜索索引、执行复杂查询和聚合分析;以及如何进行时间序列数据的存储、聚合查询和多序列联合分析。
RedisJSON模块操作与数据序列化
RedisJSON是Redis的一个强大模块,它允许在Redis中直接存储、操作和查询JSON文档。redis-py客户端提供了完整的RedisJSON命令支持,使得Python开发者能够轻松地在应用程序中使用JSON数据。
JSON数据的基本操作
设置和获取JSON数据
使用redis-py的JSON模块,您可以轻松地存储和检索JSON数据:
import redis
from redis.commands.json.path import Path
# 连接到Redis
r = redis.Redis(decode_responses=True)
# 设置JSON数据
user_data = {
"name": "张三",
"email": "zhangsan@example.com",
"age": 30,
"address": {
"city": "北京",
"street": "朝阳区"
},
"hobbies": ["阅读", "游泳", "编程"]
}
# 存储JSON对象
r.json().set("user:1001", Path.root_path(), user_data)
# 获取整个JSON对象
user = r.json().get("user:1001")
print(user)
# 输出: {'name': '张三', 'email': 'zhangsan@example.com', 'age': 30, ...}
# 获取特定路径的数据
name = r.json().get("user:1001", "$.name")
age = r.json().get("user:1001", "$.age")
city = r.json().get("user:1001", "$.address.city")
print(f"姓名: {name}, 年龄: {age}, 城市: {city}")
JSON路径表达式
RedisJSON支持强大的JSONPath表达式,允许精确访问和操作JSON文档的特定部分:
# 使用JSONPath表达式访问数据
hobbies = r.json().get("user:1001", "$.hobbies[*]")
print(f"爱好: {hobbies}") # 输出: ['阅读', '游泳', '编程']
# 使用数组索引
first_hobby = r.json().get("user:1001", "$.hobbies[0]")
print(f"第一个爱好: {first_hobby}") # 输出: '阅读'
# 使用范围选择
first_two_hobbies = r.json().get("user:1001", "$.hobbies[0:2]")
print(f"前两个爱好: {first_two_hobbies}") # 输出: ['阅读', '游泳']
数组操作
RedisJSON提供了丰富的数组操作方法:
# 数组追加
r.json().arrappend("user:1001", "$.hobbies", "摄影")
print(r.json().get("user:1001", "$.hobbies"))
# 输出: ['阅读', '游泳', '编程', '摄影']
# 数组插入
r.json().arrinsert("user:1001", "$.hobbies", 1, "音乐")
print(r.json().get("user:1001", "$.hobbies"))
# 输出: ['阅读', '音乐', '游泳', '编程', '摄影']
# 数组长度
hobbies_count = r.json().arrlen("user:1001", "$.hobbies")
print(f"爱好数量: {hobbies_count}") # 输出: 5
# 数组弹出
last_hobby = r.json().arrpop("user:1001", "$.hobbies")
print(f"弹出的爱好: {last_hobby}") # 输出: '摄影'
# 数组修剪
r.json().arrtrim("user:1001", "$.hobbies", 0, 2)
print(r.json().get("user:1001", "$.hobbies"))
# 输出: ['阅读', '音乐', '游泳']
对象操作
# 获取对象键
keys = r.json().objkeys("user:1001", "$.address")
print(f"地址对象的键: {keys}") # 输出: ['city', 'street']
# 获取对象长度
address_size = r.json().objlen("user:1001", "$.address")
print(f"地址对象的大小: {address_size}") # 输出: 2
数值操作
# 数值递增
r.json().numincrby("user:1001", "$.age", 1)
age = r.json().get("user:1001", "$.age")
print(f"增长后的年龄: {age}") # 输出: 31
# 浮点数操作
r.json().numincrby("user:1001", "$.age", 0.5)
age = r.json().get("user:1001", "$.age")
print(f"增加0.5后的年龄: {age}") # 输出: 31.5
字符串操作
# 字符串追加
r.json().strappend("user:1001", "$.name", "先生")
name = r.json().get("user:1001", "$.name")
print(f"追加后的姓名: {name}") # 输出: '张三先生'
# 字符串长度
name_length = r.json().strlen("user:1001", "$.name")
print(f"姓名长度: {name_length}") # 输出: 5
批量操作
RedisJSON支持批量操作,提高数据处理效率:
# 批量设置多个JSON文档
users = [
("user:1002", Path.root_path(), {"name": "李四", "age": 25}),
("user:1003", Path.root_path(), {"name": "王五", "age": 28}),
("user:1004", Path.root_path(), {"name": "赵六", "age": 32})
]
r.json().mset(users)
# 批量获取多个文档
user_keys = ["user:1002", "user:1003", "user:1004"]
users_data = r.json().mget(user_keys, "$")
for i, user_data in enumerate(users_data):
print(f"用户 {user_keys[i]}: {user_data}")
条件操作和存在性检查
# 仅当键不存在时设置(NX选项)
result = r.json().set("user:1005", Path.root_path(), {"name": "新用户"}, nx=True)
print(f"NX设置结果: {result}") # 如果user:1005不存在则返回True,否则返回None
# 仅当键存在时设置(XX选项)
result = r.json().set("user:1001", Path("$.age"), 35, xx=True)
print(f"XX设置结果: {result}") # 如果user:1001存在则返回True,否则返回None
# 检查JSON值的类型
data_type = r.json().type("user:1001", "$.name")
print(f"姓名类型: {data_type}") # 输出: 'string'
data_type = r.json().type("user:1001", "$.age")
print(f"年龄类型: {data_type}") # 输出: 'integer'
data_type = r.json().type("user:1001", "$.hobbies")
print(f"爱好类型: {data_type}") # 输出: 'array'
高级查询和过滤
RedisJSON支持强大的查询功能,可以使用JSONPath表达式进行复杂过滤:
# 创建一些测试数据
products = [
{
"id": "prod:1",
"name": "笔记本电脑",
"category": "电子产品",
"price": 5999.99,
"stock": 15,
"tags": ["电脑", "便携", "高性能"]
},
{
"id": "prod:2",
"name": "智能手机",
"category": "电子产品",
"price": 3999.50,
"stock": 0,
"tags": ["手机", "智能", "5G"]
},
{
"id": "prod:3",
"name": "书籍",
"category": "文化用品",
"price": 89.99,
"stock": 100,
"tags": ["阅读", "教育", "知识"]
}
]
for i, product in enumerate(products, 1):
r.json().set(f"product:{i}", Path.root_path(), product)
# 查询所有电子产品
electronics = r.json().get("product:1", "$..[?(@.category=='电子产品')]")
print(f"电子产品: {electronics}")
# 查询价格低于100的商品
cheap_products = r.json().get("product:3", "$..[?(@.price < 100)]")
print(f"低价商品: {cheap_products}")
# 查询有库存的商品
in_stock = r.json().get("product:1", "$..[?(@.stock > 0)]")
print(f"有库存商品: {in_stock}")
数据序列化和编码
redis-py的JSON模块使用Python的标准json模块进行序列化和反序列化,但提供了额外的灵活性:
from json import JSONEncoder, JSONDecoder
# 自定义编码器
class CustomEncoder(JSONEncoder):
def default(self, obj):
if isinstance(obj, set):
return list(obj)
return super().default(obj)
# 自定义解码器
class CustomDecoder(JSONDecoder):
pass
# 使用自定义编码器
r_with_custom = redis.Redis(decode_responses=True)
json_client = r_with_custom.json(encoder=CustomEncoder(), decoder=CustomDecoder())
# 存储包含特殊类型的数据
special_data = {
"name": "测试数据",
"numbers_set": {1, 2, 3, 4, 5}, # 集合类型
"timestamp": 1640995200 # Unix时间戳
}
json_client.set("special:data", Path.root_path(), special_data)
retrieved = json_client.get("special:data")
print(f"检索到的数据: {retrieved}")
错误处理和异常管理
在使用RedisJSON时,适当的错误处理非常重要:
import redis.exceptions
try:
# 尝试操作不存在的JSON键
result = r.json().get("nonexistent:key")
print(f"结果: {result}") # 输出: None
# 尝试使用无效的JSONPath
result = r.json().get("user:1001", "$.invalid.path")
print(f"无效路径结果: {result}") # 输出: []
# 尝试对非数值字段进行数值操作
r.json().numincrby("user:1001", "$.name", 1)
except redis.exceptions.ResponseError as e:
print(f"Redis错误: {e}")
except Exception as e:
print(f"其他错误: {e}")
性能优化建议
- 使用管道操作:对于批量JSON操作,使用管道可以显著提高性能
- 合理使用JSONPath:避免过于复杂的JSONPath表达式
- 数据建模:根据查询模式设计JSON文档结构
- 内存管理:监控大型JSON文档的内存使用情况
# 使用管道进行批量JSON操作
pipe = r.json().pipeline()
pipe.set("temp:1", Path.root_path(), {"data": "value1"})
pipe.set("temp:2", Path.root_path(), {"data": "value2"})
pipe.set("temp:3", Path.root_path(), {"data": "value3"})
results = pipe.execute()
print(f"管道操作结果: {results}")
RedisJSON模块为Python开发者提供了强大的JSON数据处理能力,结合redis-py客户件的优秀设计,使得在Redis中处理JSON数据变得简单而高效。通过合理使用JSONPath表达式和各种操作命令,可以构建出灵活且高性能的JSON数据存储和查询解决方案。
RediSearch全文搜索功能集成
Redis-py通过其强大的RediSearch模块提供了完整的全文搜索功能集成,使开发者能够在Redis中构建高性能的搜索引擎。RediSearch不仅仅是简单的关键字匹配,它提供了丰富的搜索功能、复杂的查询语法、聚合分析以及多种字段类型的支持。
核心架构与设计模式
RediSearch在redis-py中的实现采用了模块化的架构设计,通过专门的命令类和数据结构来封装搜索功能:
索引创建与字段类型
RediSearch支持多种字段类型,每种类型都有特定的索引和搜索特性:
| 字段类型 | 描述 | 适用场景 |
|---|---|---|
| TextField | 全文文本字段,支持分词和词干提取 | 文章内容、产品描述 |
| NumericField | 数值字段,支持范围查询 | 价格、年龄、评分 |
| TagField | 标签字段,支持精确匹配和分组 | 分类、标签、状态 |
| GeoField | 地理坐标字段,支持地理位置查询 | 地理位置、附近搜索 |
| VectorField | 向量字段,支持相似性搜索 | 推荐系统、图像搜索 |
创建索引示例:
from redis.commands.search.field import TextField, NumericField, TagField
from redis.commands.search.index_definition import IndexDefinition
# 定义索引schema
schema = (
TextField("title", weight=5.0), # 标题字段,权重更高
TextField("content"), # 内容字段
NumericField("price"), # 价格字段
TagField("category"), # 分类标签
NumericField("rating") # 评分字段
)
# 创建索引
r.ft("products").create_index(
schema,
definition=IndexDefinition(prefix=["product:"])
)
高级查询功能
RediSearch提供了丰富的查询构建功能,支持复杂的搜索场景:
基本查询操作
from redis.commands.search.query import Query, NumericFilter
# 简单全文搜索
results = r.ft().search("redis database")
# 带过滤条件的查询
query = Query("database").add_filter(NumericFilter("price", 100, 500))
results = r.ft().search(query)
# 分页和排序
query = Query("search").paging(0, 10).sort_by("rating", asc=False)
results = r.ft().search(query)
查询构建器模式
RediSearch的Query类采用了流畅的构建器模式,支持链式调用:
# 复杂的查询构建
query = (Query("programming language")
.paging(0, 20) # 分页
.sort_by("popularity", asc=False) # 排序
.return_fields("title", "author") # 返回指定字段
.with_scores() # 包含评分
.verbatim() # 精确匹配
.slop(2)) # 允许词语间隔
results = r.ft().search(query)
聚合分析功能
RediSearch提供了强大的聚合功能,支持复杂的数据分析:
import redis.commands.search.aggregation as aggregations
import redis.commands.search.reducers as reducers
# 按分类分组并计算平均价格
agg_request = (aggregations.AggregateRequest("*")
.group_by(["@category"],
reducers.avg("@price").alias("avg_price"))
.sort_by("@avg_price", asc=False))
aggregation_results = r.ft().aggregate(agg_request)
# 多维度聚合分析
complex_agg = (aggregations.AggregateRequest("redis")
.group_by(["@category", "@author"],
reducers.count().alias("count"),
reducers.avg("@rating").alias("avg_rating"))
.apply(price_range="floor(@price/100)*100")
.sort_by("@count", asc=False))
批量索引与性能优化
对于大规模数据索引,RediSearch提供了批量处理机制:
# 使用批量索引器提高性能
indexer = r.ft().batch_indexer(chunk_size=1000)
for i in range(10000):
document = {
"title": f"Document {i}",
"content": f"This is the content of document {i}",
"category": "test",
"views": i * 10
}
indexer.add_document(f"doc:{i}", **document)
# 手动提交剩余文档
indexer.commit()
搜索语法与高级特性
RediSearch支持丰富的搜索语法:
| 语法 | 示例 | 描述 |
|---|---|---|
| 布尔搜索 | python AND redis | 逻辑与操作 |
| 短语搜索 | "redis database" | 精确短语匹配 |
| 通配符 | redis* | 前缀匹配 |
| 字段搜索 | @title:redis | 指定字段搜索 |
| 范围查询 | @price:[100 500] | 数值范围查询 |
| 标签查询 | @category:{tech\|programming} | 标签多选 |
# 复杂搜索语法示例
complex_query = """
(@title:redis OR @title:database)
AND @price:[50 200]
AND @category:{tech}
-@status:outofstock
"""
results = r.ft().search(complex_query)
实时搜索与自动完成
RediSearch还提供了搜索建议和自动完成功能:
# 添加搜索建议
r.ft().sugadd("search_suggestions",
["redis", "redis-py", "redis cluster", "redis sentinel"],
[1.0, 0.8, 0.6, 0.5])
# 获取搜索建议
suggestions = r.ft().sugget("search_suggestions", "red",
fuzzy=True, num=5, with_scores=True)
性能监控与调试
RediSearch提供了详细的性能监控和查询分析功能:
# 获取索引信息
index_info = r.ft().info()
print(f"文档数量: {index_info['num_docs']}")
print(f"索引大小: {index_info['inverted_sz_mb']}MB")
# 查询性能分析
profile_results = r.ft().profile(Query("redis"), limited=True)
集成最佳实践
在实际项目中集成RediSearch时,建议遵循以下最佳实践:
- 合理的索引设计:根据查询模式设计字段和权重
- 批量操作:使用批量索引器处理大量数据
- 查询优化:使用合适的查询语法和过滤器
- 监控告警:定期监控索引性能和资源使用
- 备份策略:建立索引备份和恢复机制
RediSearch通过redis-py的集成提供了企业级的搜索解决方案,无论是简单的关键字搜索还是复杂的多条件查询,都能提供出色的性能和丰富的功能。其模块化的设计和流畅的API使得开发者可以轻松构建强大的搜索功能,同时保持代码的清晰和可维护性。
RedisTimeSeries时间序列数据分析
RedisTimeSeries模块为Redis提供了强大的时间序列数据处理能力,通过redis-py客户端可以轻松实现高效的时间序列数据存储、查询和分析。本节将深入探讨RedisTimeSeries的数据分析功能,包括聚合操作、多时间序列查询、过滤和统计功能。
聚合操作与数据分析
RedisTimeSeries支持丰富的聚合函数,可以对时间序列数据进行多种统计分析。以下是支持的聚合类型:
| 聚合类型 | 描述 | 适用场景 |
|---|---|---|
avg | 平均值 | 计算时间段内的平均数值 |
sum | 求和 | 计算时间段内的数值总和 |
min | 最小值 | 找出时间段内的最小数值 |
max | 最大值 | 找出时间段内的最大数值 |
range | 范围值 | 计算最大值与最小值的差 |
count | 计数 | 统计时间段内的数据点数量 |
first | 第一个值 | 获取时间段内的第一个数据点 |
last | 最后一个值 | 获取时间段内的最后一个数据点 |
std.p | 总体标准差 | 计算总体标准差统计 |
std.s | 样本标准差 | 计算样本标准差统计 |
var.p | 总体方差 | 计算总体方差统计 |
var.s | 样本方差 | 计算样本方差统计 |
twa | 时间加权平均 | 计算时间加权平均值 |
聚合查询示例
import redis
# 创建Redis连接
r = redis.Redis(decode_responses=True)
# 创建时间序列并添加示例数据
r.ts().create("temperature:sensor1")
for i in range(100):
r.ts().add("temperature:sensor1", i, 20 + (i % 10))
# 按10个时间单位进行聚合分析
result = r.ts().range(
"temperature:sensor1",
"-",
"+",
aggregation_type="avg",
bucket_size_msec=10
)
print("每10个时间单位的平均温度:", result)
# 计算统计指标
stats = {
"avg": r.ts().range("temperature:sensor1", "-", "+", aggregation_type="avg", bucket_size_msec=100)[0][1],
"max": r.ts().range("temperature:sensor1", "-", "+", aggregation_type="max", bucket_size_msec=100)[0][1],
"min": r.ts().range("temperature:sensor1", "-", "+", aggregation_type="min", bucket_size_msec=100)[0][1],
"std": r.ts().range("temperature:sensor1", "-", "+", aggregation_type="std.p", bucket_size_msec=100)[0][1]
}
print("统计指标:", stats)
多时间序列联合分析
RedisTimeSeries支持同时对多个时间序列进行查询和分析,特别适用于比较不同数据源或不同维度的数据。
# 创建多个传感器数据
sensors = ["sensor:temp:room1", "sensor:temp:room2", "sensor:humidity:room1"]
for sensor in sensors:
r.ts().create(sensor, labels={"type": sensor.split(":")[1], "location": sensor.split(":")[2]})
# 添加模拟数据
for i in range(50):
value = 20 + (i % 8) if "temp" in sensor else 40 + (i % 15)
r.ts().add(sensor, i, value)
# 多时间序列范围查询
results = r.ts().mrange(
"-",
"+",
filters=["type=temp"],
with_labels=True
)
print("所有温度传感器的数据:", results)
# 按标签筛选和聚合
room1_stats = r.ts().mrange(
"-",
"+",
filters=["location=room1"],
aggregation_type="avg",
bucket_size_msec=10,
select_labels=["type"]
)
print("Room1各类型传感器平均值:", room1_stats)
高级过滤与数据筛选
RedisTimeSeries提供了强大的过滤功能,可以基于时间戳、数值范围等条件进行精确的数据筛选。
# 基于时间戳过滤
filtered_by_ts = r.ts().range(
"temperature:sensor1",
"-",
"+",
filter_by_ts=[10, 20, 30, 40, 50]
)
print("特定时间戳的数据:", filtered_by_ts)
# 基于数值范围过滤
filtered_by_value = r.ts().range(
"temperature:sensor1",
"-",
"+",
filter_by_min_value=22,
filter_by_max_value=26
)
print("温度在22-26度之间的数据:", filtered_by_value)
# 组合过滤条件
combined_filter = r.ts().range(
"temperature:sensor1",
"-",
"+",
filter_by_ts=[15, 25, 35, 45],
filter_by_min_value=23,
filter_by_max_value=27,
count=2 # 限制返回结果数量
)
print("组合过滤结果:", combined_filter)
时间序列数据统计与元数据
实际应用案例:物联网数据分析
以下是一个完整的物联网温度监控数据分析示例:
class TemperatureAnalyzer:
def __init__(self, redis_client):
self.r = redis_client
def store_temperature_data(self, sensor_id, timestamp, temperature):
"""存储温度数据"""
key = f"temperature:{sensor_id}"
return self.r.ts().add(key, timestamp, temperature)
def get_daily_stats(self, sensor_id, date_range):
"""获取每日统计"""
stats = {}
for stat_type in ["avg", "min", "max", "std.p"]:
result = self.r.ts().range(
f"temperature:{sensor_id}",
date_range[0],
date_range[1],
aggregation_type=stat_type,
bucket_size_msec=24 * 60 * 60 * 1000 # 每日聚合
)
stats[stat_type] = result[0][1] if result else None
return stats
def compare_sensors(self, sensor_ids, time_range):
"""比较多个传感器数据"""
filters = [f"sensor_id={sensor_id}" for sensor_id in sensor_ids]
return self.r.ts().mrange(
time_range[0],
time_range[1],
filters=filters,
aggregation_type="avg",
bucket_size_msec=60 * 60 * 1000 # 每小时聚合
)
def detect_anomalies(self, sensor_id, threshold=2.0):
"""异常检测基于标准差"""
current_data = self.r.ts().get(f"temperature:{sensor_id}")
if not current_data:
return None
historical_std = self.r.ts().range(
f"temperature:{sensor_id}",
"-",
current_data[0] - 3600000, # 前一小时数据
aggregation_type="std.p",
bucket_size_msec=3600000
)
if historical_std and abs(current_data[1] - historical_std[0][1]) > threshold:
return {
"timestamp": current_data[0],
"value": current_data[1],
"deviation": abs(current_data[1] - historical_std[0][1])
}
return None
# 使用示例
analyzer = TemperatureAnalyzer(r)
analyzer.store_temperature_data("sensor1", 1640995200000, 22.5)
daily_stats = analyzer.get_daily_stats("sensor1", (1640995200000, 1641081600000))
print("每日统计:", daily_stats)
性能优化与最佳实践
- 数据压缩配置:根据数据特性选择合适的压缩设置
- 聚合预处理:对于频繁查询的聚合结果,可以考虑使用规则进行预处理
- 标签优化:合理使用标签进行数据分类和快速检索
- 内存管理:根据数据保留策略设置合适的retention period
# 优化配置示例
r.ts().create(
"optimized:metric",
retention_msecs=7 * 24 * 60 * 60 * 1000, # 保留7天数据
chunk_size=4096, # 优化内存使用
labels={"category": "performance", "env": "production"}
)
RedisTimeSeries通过redis-py提供的丰富API,使得时间序列数据分析变得简单而高效,特别适合物联网、监控系统、金融数据分析等场景。
向量搜索与AI应用集成
在现代AI应用中,向量搜索已成为实现语义搜索、推荐系统和相似性匹配的核心技术。Redis通过VectorSet模块提供了强大的向量搜索能力,结合redis-py客户端,开发者可以轻松构建高性能的AI应用。
VectorSet核心功能概述
Redis VectorSet模块提供了一套完整的向量操作命令,支持高维向量的存储、检索和相似性搜索。其主要特性包括:
- 高效相似性搜索:基于HNSW算法实现近似最近邻搜索
- 多种量化选项:支持无量化、二进制量化和8位量化
- 维度缩减:支持随机投影降维技术
- 属性过滤:支持基于JSON属性的混合搜索
- 多链接优化:可配置的邻居链接数量优化搜索性能
核心API详解
向量添加与存储
import redis
from redis.commands.vectorset.commands import QuantizationOptions
# 初始化Redis连接
r = redis.Redis(decode_responses=True)
# 添加向量到集合
vector = [0.1, 0.2, 0.3, 0.4, 0.5]
result = r.vset().vadd(
"product_vectors",
vector,
"product_123",
quantization=QuantizationOptions.Q8, # 8位量化
attributes={"category": "electronics", "price": 299.99}
)
print(f"添加结果: {result}") # 输出: 1
相似性搜索操作
# 基本相似性搜索
query_vector = [0.12, 0.22, 0.32, 0.42, 0.52]
similar_items = r.vset().vsim("product_vectors", query_vector)
print(f"相似商品: {similar_items}")
# 带分数和属性的高级搜索
detailed_results = r.vset().vsim(
"product_vectors",
query_vector,
with_scores=True,
with_attribs=True,
count=5,
filter='.category == "electronics" && .price < 300'
)
print(f"详细结果: {detailed_results}")
AI应用集成模式
文本嵌入与搜索流水线
import numpy as np
from sentence_transformers import SentenceTransformer
# 初始化文本嵌入模型
model = SentenceTransformer('all-MiniLM-L6-v2')
class VectorSearchEngine:
def __init__(self, redis_client, index_name="doc_vectors"):
self.redis = redis_client
self.index_name = index_name
self.model = model
def index_document(self, doc_id, text, metadata=None):
"""索引文本文档"""
# 生成文本嵌入向量
embedding = self.model.encode(text).tolist()
# 存储到Redis
attributes = {"text": text, "metadata": metadata or {}}
return self.redis.vset().vadd(
self.index_name,
embedding,
doc_id,
attributes=attributes
)
def search_similar(self, query_text, top_k=10, filters=None):
"""搜索相似文档"""
query_embedding = self.model.encode(query_text).tolist()
search_params = {
"input": query_embedding,
"count": top_k,
"with_scores": True
}
if filters:
search_params["filter"] = filters
return self.redis.vset().vsim(self.index_name, **search_params)
# 使用示例
search_engine = VectorSearchEngine(r)
search_engine.index_document("doc1", "机器学习算法介绍", {"category": "技术"})
search_engine.index_document("doc2", "深度学习框架比较", {"category": "技术"})
results = search_engine.search_similar("人工智能算法", top_k=5)
print(f"搜索结果: {results}")
推荐系统实现
class RecommendationSystem:
def __init__(self, redis_client):
self.redis = redis_client
def add_user_preference(self, user_id, item_vectors):
"""添加用户偏好向量"""
for item_id, vector in item_vectors.items():
self.redis.vset().vadd(
f"user_{user_id}_preferences",
vector,
item_id
)
def get_recommendations(self, user_id, candidate_items, top_n=10):
"""基于用户偏好生成推荐"""
user_preferences = f"user_{user_id}_preferences"
recommendations = {}
for item_id, vector in candidate_items.items():
similarity = self.redis.vset().vsim(
user_preferences,
vector,
with_scores=True,
count=1
)
if similarity:
recommendations[item_id] = max(similarity.values())
# 返回Top-N推荐
return dict(sorted(recommendations.items(),
key=lambda x: x[1],
reverse=True)[:top_n])
性能优化策略
量化策略选择
# 不同量化策略的性能比较
quantization_strategies = {
"NOQUANT": QuantizationOptions.NOQUANT, # 无量化,精度最高
"Q8": QuantizationOptions.Q8, # 8位量化,平衡精度和性能
"BIN": QuantizationOptions.BIN # 二进制量化,性能最优
}
def benchmark_quantization(strategy_name, strategy, test_vectors):
"""量化策略性能测试"""
import time
start_time = time.time()
for i, vector in enumerate(test_vectors):
r.vset().vadd(
f"benchmark_{strategy_name}",
vector,
f"item_{i}",
quantization=strategy
)
# 测试搜索性能
search_time = time.time()
r.vset().vsim(f"benchmark_{strategy_name}", test_vectors[0])
end_time = time.time()
return {
"index_time": search_time - start_time,
"search_time": end_time - search_time,
"memory_usage": r.vset().vcard(f"benchmark_{strategy_name}")
}
维度优化配置
实际应用场景
电商商品推荐
class ECommerceRecommender:
def __init__(self, redis_client):
self.redis = redis_client
def index_product(self, product_id, features, metadata):
"""索引商品特征"""
# 特征向量化
feature_vector = self._extract_features(features)
return self.redis.vset().vadd(
"products",
feature_vector,
product_id,
attributes=metadata
)
def recommend_similar_products(self, product_id, user_filters=None, limit=8):
"""推荐相似商品"""
# 获取目标商品向量
target_vector = self.redis.vset().vemb("products", product_id)
if not target_vector:
return []
search_params = {
"input": target_vector,
"count": limit + 1, # 包含自己
"with_scores": True
}
if user_filters:
filter_expr = " && ".join([f'.{k} == "{v}"' for k, v in user_filters.items()])
search_params["filter"] = filter_expr
results = self.redis.vset().vsim("products", **search_params)
# 移除自身并返回推荐结果
return {k: v for k, v in results.items() if k != product_id}
def _extract_features(self, features):
"""特征提取方法"""
# 实际应用中可能使用深度学习模型提取特征
return [features.get('price', 0) / 1000,
features.get('rating', 0) / 5,
len(features.get('category', '')) / 10]
内容检索系统
class ContentRetrievalSystem:
def __init__(self, redis_client):
self.redis = redis_client
self.content_types = ["article", "video", "image", "audio"]
def add_content(self, content_id, content_type, embedding, metadata):
"""添加内容到检索系统"""
if content_type not in self.content_types:
raise ValueError(f"不支持的内容类型: {content_type}")
attributes = {
"type": content_type,
"metadata": metadata,
"timestamp": datetime.now().isoformat()
}
return self.redis.vset().vadd(
f"content_{content_type}",
embedding,
content_id,
attributes=attributes
)
def cross_modal_search(self, query_embedding, content_types=None, filters=None):
"""跨模态内容搜索"""
results = {}
target_types = content_types or self.content_types
for content_type in target_types:
index_name = f"content_{content_type}"
search_params = {
"input": query_embedding,
"count": 10,
"with_scores": True
}
if filters:
search_params["filter"] = filters
type_results = self.redis.vset().vsim(index_name, **search_params)
results[content_type] = type_results
return results
监控与维护
性能监控指标
class VectorSearchMonitor:
def __init__(self, redis_client):
self.redis = redis_client
def get_index_stats(self, index_name):
"""获取向量索引统计信息"""
return {
"cardinality": self.redis.vset().vcard(index_name),
"dimensions": self.redis.vset().vdim(index_name),
"memory_usage": self._estimate_memory_usage(index_name)
}
def monitor_search_performance(self, index_name, sample_queries, num_runs=100):
"""监控搜索性能"""
import time
latencies = []
for _ in range(num_runs):
query_vector = random.choice(sample_queries)
start_time = time.perf_counter()
self.redis.vset().vsim(index_name, query_vector, count=10)
latencies.append(time.perf_counter() - start_time)
return {
"avg_latency": sum(latencies) / len(latencies),
"p95_latency": sorted(latencies)[int(0.95 * len(latencies))],
"max_latency": max(latencies)
}
def _estimate_memory_usage(self, index_name):
"""估算内存使用量"""
# 简化估算:维度数 × 元素数 × 4字节(float32)
dim = self.redis.vset().vdim(index_name)
card = self.redis.vset().vcard(index_name)
return dim * card * 4 # 字节数
通过redis-py的VectorSet模块,开发者可以构建出高性能、可扩展的AI应用系统,满足现代应用对实时向量搜索的需求。其丰富的API和灵活的配置选项使其成为AI应用集成中的理想选择。
总结
Redis通过其强大的模块生态系统,极大地扩展了其核心数据结构的功能边界。RedisJSON提供了灵活的JSON文档操作能力,RediSearch实现了企业级的全文搜索功能,RedisTimeSeries则专注于高效的时间序列数据处理。结合redis-py客户端,开发者可以在Python应用中轻松集成这些高级功能,构建出高性能、可扩展的数据密集型应用。文章通过大量的实际代码示例,系统地展示了各模块的核心API和最佳实践,为开发者提供了全面的技术参考和实现指南。
【免费下载链接】redis-py Redis Python Client 项目地址: https://gitcode.com/GitHub_Trending/re/redis-py
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



