小谈Redis JSON 系列一
写在前面的话
本文是笔者自己查询所能搜到的文档、视频资料整理所得,因原材料均为英文(具体材料见文章最后的参考文档),所以存在理解误差在所难免,欢迎大家进行探讨,并指出我的错误。
JSON是一个轻量级的数据交换格式,我所在的公司前后端便是通过JSON这种数据格式进行信息交互的。
Redis也是软件开发提高性能必不可少的中间件。
那么将JSON形式的数据放入Redis数据库中也是不可避免的操作。
这是系列第一篇,主要通过Redis对JSON的传统操作,从而引出Redis JSON这个本文的主角。
下面首先会讲一下,在Redis中传统操作JSON数据的两种方式。
Redis操作JSON的传统办法
Raw String 纯字符串
将JSON数据,以string的方式放入Redis中。
使用方法
# 放置JSON
> set tag '{"1":{"tag":"GOAL_SELECT_TAG","execTs":1640676319},"2":{"tag":"GOAL_SELECT_TAG","execTs":1640676319}}'
OK
# 获取JSON
> get tag
{"1":{"tag":"GOAL_SELECT_TAG","execTs":1640676319},"2":{"tag":"GOAL_SELECT_TAG","execTs":1640676319}}
优点
- 占用内存小
缺点
JSON数据中键级别的访问和修改是不支持的。采用string形式,只能全量获取
Hash 数据结构
将JSON数据使用HASH的形式放入Redis中。
使用方法
# 放置JSON
> hset h name zm age 16
2
# 获取JSON
> hgetall h
name
zm
age
16
> hget h name
zm
优点
- 提供
JSON键级别的访问和修改,并且时间复杂度为O(1)
缺点
JSON键的值只能为字符串或者数值,也就是说采用HASH的方式存储,JSON数据只能有一级,不能嵌套。比如
{
"1": {
"tag": "GOAL_SELECT_TAG",
"execTs": 1640676319
},
"2": {
"tag": "GOAL_SELECT_TAG",
"execTs": 1640676319
}
}
- 占用内存较
string大
Redis JSON
Redis JSON 是Redis Modules中的一个。
Redis Module

Redis JSON
就像Redis的其他数据类型一样,
Redis JSON新增了一种类型,且该类型在树的节点中以二进制的方式存储数据(ReJSON stores the data in binary format in the tree’s nodes)。具体详见下面的实操。Redis JSON提供了一系列API来操作JSON 数据。
Redis JSON启动与上手
操作环境搭建
- 先去redis cloud上注册,申请免费的数据库,并且添加
Redis JSON以及Redis Search两个Modules。 - 根据上述生成的数据库配置项,采用终端或者客户端软件连接该
Redis。 这样,我们就可以进行Redis JSON的操作。
与此同时,发现的两个bug
-
Redis Cloud中的拼写错误
-
Red客户端的错误
一个Redis JSON命令的样例

JSON.SET key $ '{"foo":"bar", "ans": 42}'
JSON.SET:设置JSON的命令。Redis JSON的所有命令都需要带有JSON前缀key:具体的key名- $ :表示根路径。为了获取
JSON中不同层级的键值,JSON有自己的一套查询语言,详见JSONPath '{"foo":"bar", "ans": 42}':JSON字符串
由此可见,Redis JSON的命令与普通Redis命令的差异之处在于有一个Path的说法,Path就是为了方便且统一的解析JSON数据(虽然现在并没有统一...)
There are at least two standards for JSON paths ...which means there is no standard for JSON paths.
Redis JSON 命令
常见命令演示
首先给定一个JSON数据
{
"1": {
"tag": "GOAL_SELECT_TAG",
"execTs": 1640676319
},
"2": {
"tag": "GOAL_SELECT_TAG",
"execTs": 1640676319
}
}
- 设置
JSON
2022-01-10 20:22:44 JSON.SET tag $ '{"1":{"tag":"GOAL_SELECT_TAG","execTs":1640676319},"2":{"tag":"GOAL_SELECT_TAG","execTs":1640676319}}'
OK
- 获取键为
1的内容
2022-01-11 21:37:36 JSON.GET tag $.1
[{"tag":"GOAL_SELECT_TAG","execTs":1640676319}]
- 获取键为
2的tag内容
2022-01-11 21:38:45 JSON.GET tag $.2.tag
["GOAL_SELECT_TAG"]
- 遍历获取
tag值,返回数组
2022-01-10 20:23:01 JSON.GET tag $..tag
["GOAL_SELECT_TAG","GOAL_SELECT_TAG"]
- 增加或者减少键为
1的execTs数值
// 获取
2022-01-12 18:34:49 JSON.GET tag $.1
[{"tag":"GOAL_SELECT_TAG","execTs":1640676980}]
// 减少980
2022-01-12 18:35:00 JSON.NUMINCRBY tag $.1.execTs -980
// 最新的结果
[1640676000]
命令总结

- 对应
JSON的不同组成部分Redis JSON提供相应的命令 - 根据命令名称便能对其功能猜测一二,根据具体的需求各取所需,到时候参考官方文档即可。
总结
Redis JSON是为了能够操作JSON数据而存在的。- 命令的使用与普通
Redis命令的差异之处在于Path的概念。 - 为了更好的操作
JSON数据,Path是不可避免的。可以学习一下JSONPath的使用。 - 对于一个
Redis命令来说,重要的除了功能之外,最重要的是命令对应的时间复杂度。但是其官方文档对其语焉不详,故本文为多做阐释,以免贻误大家。
这是Redis JSON的第一篇文章,下面会可能就在实际项目中、命令时间复杂度、整体性能等方面进行撰文阐释,敬请期待。
参考文档
RedisJSON — Manipulando JSON como tipo nativo no Redis
JSON in Redis - When to use RedisJSON
RedisJSON + RediSearch as a real-time document database, Redis Labs
转载自:https://juejin.cn/post/7052271318598680613