Redis®*: 搜索与 JSON
使用 Redis 查询引擎高效存储和查询 JSON 文档
👋 欢迎查阅 Stackhero 文档!
Stackhero 提供即开即用的 Redis cloud 解决方案,带来多项优势,包括:
- 集成
Redis CommanderWeb 管理界面。- 无限制的消息大小与传输。
- 一键完成升级,操作便捷。
- 基于专属私有基础设施,实现卓越性能与强大安全性。
节省时间,简化运维:仅需 5 分钟即可体验 Stackhero 的 Redis cloud 托管 方案!
您在 Stackhero 上的 Redis 实例包含了 Redis Open Source 提供的所有模块。这些模块让 Redis 不仅仅是一个缓存:您可以直接存储真实的 JSON 文档,对其建立索引,并进行全文、本地数值和标签查询,无需为您的技术栈再添加其他数据库。
以下四个模块均包含在您的套餐中:
- JSON(
JSON.*命令):为 Redis 增加了原生 JSON 类型,并支持 JSONPath。您可以读取或更新单个字段,无需重写整个文档。 - Search(
FT.*命令),也称为 Redis 查询引擎:提供全文搜索、二级索引、聚合和向量搜索能力。 - Bloom(
BF.*、CF.*、CMS.*、TOPK.*、TDIGEST.*命令):概率型数据结构,可在大规模数据集上用极少内存高效回答“我是否已经见过这个?”等问题。 - Time series(
TS.*命令):提供时间序列类型,支持数据保留、降采样和聚合功能。
Vector sets(VADD、VSIM)直接内置于 Redis 内核。这些功能支持高效的向量相似度搜索(如 embeddings),在您的服务中始终可用,无需额外配置。
启用模块
模块默认处于禁用状态。这确保了现有服务在您主动启用新功能前保持原有行为。
- 在 Stackhero 控制台 打开您的服务。
- 进入服务配置页面。
- 在 Modules 部分,选择您需要的模块。
- 保存更改。
您的 Redis 服务会重启并加载所选模块。整个过程通常只需几秒钟。
一旦您通过某个模块(如 JSON 文档、Bloom filter 或 time series)存储了数据,请务必保持该模块处于启用状态。Redis 无法访问由已禁用模块创建的数据,禁用后服务将无法启动。Vector sets 始终可用,因为它们是 Redis 的一部分。
要检查当前已加载的模块,可以运行:
redis-cli -u "rediss://default:<yourPassword>@<XXXXXX>.stackhero-network.com:<PORT_TLS>" MODULE LIST
存储 JSON 文档
您可以将文档以原生 JSON 形式存储,而无需序列化为字符串:
JSON.SET product:1 $ '{"name":"Espresso machine","brand":"Bianca","price":459,"tags":["coffee","kitchen"],"stock":12}'
这种方式允许您在服务器端原子性地读取或更新单个字段:
JSON.GET product:1 $.price
# "[459]"
JSON.NUMINCRBY product:1 $.stock -1
# "[11]"
JSON.ARRAPPEND product:1 $.tags '"gift"'
这种工作流可以简化开发并减少错误。例如,减少库存计数时,无需在应用端读取、解析和重写整个文档,所有操作都在服务器端安全且即时完成。
完整命令列表请参见 Redis JSON 文档。
对文档建立索引与搜索
您只需声明一次索引,Redis 会自动为所有匹配指定前缀的 key 保持索引最新,包括索引创建前已存在的 key。
FT.CREATE productsIndex
ON JSON
PREFIX 1 product:
SCHEMA
$.name AS name TEXT
$.brand AS brand TAG
$.price AS price NUMERIC SORTABLE
$.tags[*] AS tags TAG
现在您可以执行如下查询:
# 对名称进行全文搜索,并限定价格区间
FT.SEARCH productsIndex "@name:(espresso) @price:[0 500]"
# 精确匹配品牌,并按价格排序
FT.SEARCH productsIndex "@brand:{Bianca}" SORTBY price ASC
# 前缀搜索,适用于自动补全场景
FT.SEARCH productsIndex "@name:(espr*)"
Redis 还可以直接在索引上进行聚合分析,无需导出数据即可满足分析型查询需求:
FT.AGGREGATE productsIndex "*"
GROUPBY 1 @brand
REDUCE COUNT 0 AS products
REDUCE AVG 1 @price AS averagePrice
SORTBY 2 @products DESC
如果您将数据以普通 hash 结构存储而非 JSON,可以在 schema 中使用 ON HASH 和标准字段名。
示例:Node.js 使用方法
import { createClient, SCHEMA_FIELD_TYPE } from 'redis';
const client = createClient({ url: process.env.STACKHERO_REDIS_URL_TLS });
await client.connect();
// 启动时创建索引
try {
await client.ft.create(
'productsIndex',
{
'$.name': { type: SCHEMA_FIELD_TYPE.TEXT, AS: 'name' },
'$.brand': { type: SCHEMA_FIELD_TYPE.TAG, AS: 'brand' },
'$.price': { type: SCHEMA_FIELD_TYPE.NUMERIC, AS: 'price', SORTABLE: true }
},
{ ON: 'JSON', PREFIX: 'product:' }
);
}
catch (error) {
if (!error.message.includes('Index already exists')) {
throw error;
}
}
await client.json.set('product:1', '$', {
name: 'Espresso machine',
brand: 'Bianca',
price: 459
});
const results = await client.ft.search('productsIndex', '@name:(espresso) @price:[0 500]');
console.log(results.total, results.documents);
await client.quit();
示例:Python 使用方法
import os
import redis
from redis.commands.search.field import TextField, TagField, NumericField
from redis.commands.search.index_definition import IndexDefinition, IndexType
from redis.commands.search.query import Query
r = redis.from_url(os.environ['STACKHERO_REDIS_URL_TLS'], decode_responses=True)
# 启动时创建索引
try:
r.ft('productsIndex').create_index(
(
TextField('$.name', as_name='name'),
TagField('$.brand', as_name='brand'),
NumericField('$.price', as_name='price', sortable=True),
),
definition=IndexDefinition(prefix=['product:'], index_type=IndexType.JSON),
)
except redis.ResponseError as error:
if 'Index already exists' not in str(error):
raise
r.json().set('product:1', '$', {
'name': 'Espresso machine',
'brand': 'Bianca',
'price': 459,
})
results = r.ft('productsIndex').search(Query('@name:(espresso) @price:[0 500]'))
print(results.total, results.docs)
温馨提示
- Search 索引仅适用于数据库 0。 在其他数据库上执行
FT.CREATE会返回错误。如果您的应用使用多个逻辑数据库,请将可索引数据保存在数据库 0,或通过 key 前缀区分不同数据集。 - 索引占用套餐内存,与数据一样。 大型文本或向量索引可能占用较多内存,建议在构建后通过 Prometheus 指标 监控
used_memory。 - 在已有 key 上创建索引会在后台异步进行。 刚执行
FT.CREATE后,搜索结果可能暂时不完整。您可以通过FT.INFO productsIndex监控索引进度。 - 所有模块命令均可用。 每个已启用模块的所有命令都可在您的服务中直接使用。
如需了解更多关于向量相似度、语义搜索或检索增强生成(RAG)的内容,请参阅 向量搜索指南。