文章目錄
- 一、寫在前面
- 二、使用
- 1、基本命令
- (1)JSON.SET 設置 JSON 值
- (2)JSON.GET 獲取 JSON 值
- (3)JSON.DEL 刪除 JSON 值
- (4)JSON.MGET 批量獲取
- (5)JSON.MSET 批量插入
- 2、數組命令
- (1)JSON.ARRAPPEND 數組追加元素
- (2)JSON.ARRINSERT 數組插入元素
- (3)JSON.ARRLEN 獲取數組長度
- (4)JSON.ARRINDEX 查找第一個索引
- (5)JSON.ARRPOP 移出并返回元素
- (6)JSON.ARRTRIM 修剪數組
- 3、對象命令
- (1)JSON.OBJKEYS 獲取所有鍵
- (2)JSON.OBJLEN獲取鍵數
- 4、數值操作
- (1)JSON.NUMINCRBY增量操作
- (2)JSON.NUMMULTBY 乘法操作
- 5、字符串操作
- (1)JSON.STRAPPEND字符串追加
- (2)JSON.STRLEN 獲取字符串長度
- 6、其他操作
- (1)JSON.TYPE 獲取類型
- (2)JSON.CLEAR 清除數組/對象
- (3)JSON.DEBUG MEMORY 查看內存
- (4)JSON.MERGE 合并
- (5)JSON.TOGGLE 切換布爾值
一、寫在前面
官方文檔:https://redis.io/docs/latest/commands/?group=json
關于在JSON命令中使用字符串:
若要將字符串指定為要追加的數組值,請用一組額外的單引號將帶引號的字符串括起來。示例:‘“silver”’
JSONPATH語法:
Redis JSON 使用 $ 表示根節點,支持嵌套路徑,例如:
$.user.address.city
$[0].name(訪問數組第一個元素的 name 字段)
二、使用
1、基本命令
(1)JSON.SET 設置 JSON 值
# 格式
# key 是修改的key
# path:要指定的JSONPath。默認值是root$。對于新的Redis鍵path一定是根。對于現有鍵,當整個path存在,則它包含的值將被替換為json value。對于現有鍵,當path存在,但最后一個元素除外,則添加一個帶有json 的value。
# NX:不存在時設置
# XX:存在時設置
JSON.SET key path value [NX | XX]
# 設置redis根的值
127.0.0.1:6379> JSON.SET doc $ '{"a":2}'
OK
127.0.0.1:6379> JSON.GET doc
"{\"a\":2}"
127.0.0.1:6379> JSON.GET doc $.a
"[2]"
# 往根添加另一個屬性
127.0.0.1:6379> JSON.SET doc $.b '8'
OK
127.0.0.1:6379> JSON.GET doc
"{\"a\":2,\"b\":8}"
# 替換值
127.0.0.1:6379> JSON.SET doc $.a '3'
OK
127.0.0.1:6379> JSON.GET doc
"{\"a\":3,\"b\":8}"
# 沒有才設置
127.0.0.1:6379> JSON.SET doc $.a '3' NX
(nil)
# 有才設置,直接替換
127.0.0.1:6379> JSON.SET doc $.a '3' XX
OK
# 設置多個值,會將root下都替換掉
127.0.0.1:6379> JSON.SET doc $ '{"f1": {"a":1}, "f2":{"a":2}}'
OK
# 設置所有的a的值為3
127.0.0.1:6379> JSON.SET doc $..a 3
OK
127.0.0.1:6379> JSON.GET doc
"{\"f1\":{\"a\":3},\"f2\":{\"a\":3}}"
# 路徑不存在無法創建
redis> JSON.SET doc $ 1
OK
redis> JSON.SET doc $.x.y 2
(nil)
# 必須優先創建根json
127.0.0.1:6379> JSON.SET nonexistentkey $.x 5
(error) ERR new objects must be created at the root
(2)JSON.GET 獲取 JSON 值
# 格式
# path:指定的JSONPath。默認值是root$。JSON。GET接受多個path參數
# INDENT 設置嵌套級別的縮進字符串。
# NEWLINE 設置打印在每行末尾的字符串。
# SPACE 設置放在鍵和值之間的字符串。
JSON.GET key [INDENT indent] [NEWLINE newline] [SPACE space] [path [path ...]]# 格式化json字符串(貌似在cli命令行不太好使,應該是得--raw的事)
~/$ redis-cli --raw
redis> JSON.GET myjsonkey INDENT "\t" NEWLINE "\n" SPACE " " path.to.value[1]
127.0.0.1:6379> JSON.SET doc $ '{"a":2, "b": 3, "nested": {"a": 4, "b": null}}'
OK
# 單個jsonpath獲取值
127.0.0.1:6379> JSON.GET doc $..b
"[3,null]"
# 多個jsonpath獲取值,會返回一個JSON字符串,該字符串包含一個頂級對象,每個路徑包含一個JSON值數組
127.0.0.1:6379> JSON.GET doc ..a $..b
"{\"..a\":[2,4],\"$..b\":[3,null]}"
(3)JSON.DEL 刪除 JSON 值
# 語法
# path:要指定的JSONPath。默認值是root$。不存在的路徑被忽略。
# 注意!刪除json的根相當于刪除整個key
JSON.DEL key [path]
127.0.0.1:6379> JSON.SET doc $ '{"a": 1, "nested": {"a": 2, "b": 3}}'
OK
# 根據jsonpath刪除數據
127.0.0.1:6379> JSON.DEL doc $..a
(integer) 2
127.0.0.1:6379> JSON.GET doc $
"[{\"nested\":{\"b\":3}}]"# 刪除根,相當于刪除整個key
127.0.0.1:6379> JSON.DEL doc $
(integer) 1
127.0.0.1:6379> JSON.GET doca $
(nil)
(4)JSON.MGET 批量獲取
警告:
啟用群集模式時,所有指定的鍵必須駐留在同一個散列槽。
# 語法
JSON.MGET key [key ...] path
redis> JSON.SET doc1 $ '{"a":1, "b": 2, "nested": {"a": 3}, "c": null}'
OK
redis> JSON.SET doc2 $ '{"a":4, "b": 5, "nested": {"a": 6}, "c": null}'
OK# 從多個文檔獲取值
redis> JSON.MGET doc1 doc2 $..a
1) "[1,3]"
2) "[4,6]"
(5)JSON.MSET 批量插入
# 語法
# JSON.MSET是原子性的,因此,所有給定的添加或更新要么被應用,要么不被應用。客戶端不可能看到一些密鑰被更新,而另一些沒有改變。
JSON.MSET key path value [key path value ...]
redis> JSON.MSET doc1 $ '{"a":1}' doc2 $ '{"f":{"a":2}}' doc3 $ '{"f1":{"a":0},"f2":{"a":0}}'
OK
redis> JSON.MSET doc1 $ '{"a":2}' doc2 $.f.a '3' doc3 $ '{"f1":{"a":1},"f2":{"a":2}}'
OK
redis> JSON.GET doc1 $
"[{\"a\":2}]"
redis> JSON.GET doc2 $
"[{\"f\":{\"a\":3}}]"
redis> JSON.GET doc3
"{\"f1\":{\"a\":1},\"f2\":{\"a\":2}}"
2、數組命令
(1)JSON.ARRAPPEND 數組追加元素
# 語法 追加到一個或多個數組中的一個或多個值。
# JSON.ARRAPPEND返回排列每個路徑的整數回復數、數組的新大小或nil
JSON.ARRAPPEND key [path] value [value ...]
127.0.0.1:6379> JSON.SET doc $ '{"name":"zhangsan","age":15,"address":"shandong","like":["sing","read"]}'
OK
# 往數組中追加一個數據,返回值為數組追加后的長度
127.0.0.1:6379> JSON.ARRAPPEND doc $.like '"write"'
1) (integer) 3
127.0.0.1:6379> JSON.GET doc
"{\"name\":\"zhangsan\",\"age\":15,\"address\":\"shandong\",\"like\":[\"sing\",\"read\",\"write\"]}"
# 非數組無法追加,返回nil
127.0.0.1:6379> JSON.ARRAPPEND doc $.name '"lisi"'
1) (nil)
(2)JSON.ARRINSERT 數組插入元素
# 語法:在index之前插入數組元素
# value 要插入一個或多個數組中的一個或多個值。
# index 是數組中要插入值的位置。索引必須在數組的范圍內。插入位置index0前置到數組。負索引值從數組的末尾開始。
JSON.ARRINSERT key path index value [value ...]
127.0.0.1:6379> JSON.SET doc $ '{"name":"zhangsan","age":15,"address":"shandong","like":["sing","read"]}'
OK
# 往數組中追加
127.0.0.1:6379> JSON.ARRAPPEND doc $.like '"write"'
1) (integer) 3
# 往數組中第二個索引位插入(從0開始計算)
127.0.0.1:6379> JSON.ARRINSERT doc $.like 2 '"run"' '"walk"'
1) (integer) 5
127.0.0.1:6379> JSON.GET doc
"{\"name\":\"zhangsan\",\"age\":15,\"address\":\"shandong\",\"like\":[\"sing\",\"read\",\"run\",\"walk\",\"write\"]}"
(3)JSON.ARRLEN 獲取數組長度
# 語法
JSON.ARRLEN key [path]
127.0.0.1:6379> JSON.SET doc $ '{"name":"zhangsan","age":15,"address":"shandong","like":["sing","read"]}'
OK
# 獲取所有對象的數組長度,如果不是數組則返回nil
127.0.0.1:6379> JSON.ARRLEN doc '$.[*]'
1) (nil)
2) (nil)
3) (nil)
4) (integer) 2
# 返回指定數組長度
127.0.0.1:6379> JSON.ARRLEN doc '$.like'
1) (integer) 2
(4)JSON.ARRINDEX 查找第一個索引
# 語法
# start:要在要搜索的數組片段中指定的起始值。默認值為0.
# stop:是要在要搜索的數組片段中指定的獨占停止值,包括最后一個元素。默認值為0。負值被解釋為從末尾開始。
#關于超出范圍的索引:超出范圍的索引舍入到數組的開頭和結尾。反向索引范圍(如從1到0的范圍)返回unfound或-1.
JSON.ARRINDEX key path value [start [stop]]# 實例
127.0.0.1:6379> JSON.SET doc $ '{"name":"zhangsan","age":15,"address":"shandong","like":["sing","read"]}'
OK
# 返回索引位置
127.0.0.1:6379> JSON.ARRINDEX doc $.like '"read"'
1) (integer) 1
127.0.0.1:6379> JSON.ARRINDEX doc $.like '"sing"'
1) (integer) 0
# 返回-1則表示未找到,nil表示不是數組
127.0.0.1:6379> JSON.ARRINDEX doc $.like '"run"'
1) (integer) -1
(5)JSON.ARRPOP 移出并返回元素
# 語法 從數組的索引中移除并返回一個元素
# index:是數組中開始彈出的位置。默認值為-1,意思是最后一個元素。超出范圍的索引舍入到各自的數組末尾。彈出空數組會返回null。
JSON.ARRPOP key [path [index]]
127.0.0.1:6379> JSON.SET doc $ '{"name":"zhangsan","age":15,"address":"shandong","like":["sing","read"]}'
OK
# 數組第0個位置移出
127.0.0.1:6379> JSON.ARRPOP doc $.like 0
1) "\"sing\""
127.0.0.1:6379> JSON.GET doc
"{\"name\":\"zhangsan\",\"age\":15,\"address\":\"shandong\",\"like\":[\"read\"]}"
# 數組第0個位置插入,模擬了數組中數據的替換
127.0.0.1:6379> JSON.ARRINSERT doc $.like 0 '"run"'
1) (integer) 2
127.0.0.1:6379> JSON.GET doc
"{\"name\":\"zhangsan\",\"age\":15,\"address\":\"shandong\",\"like\":[\"run\",\"read\"]}"
(6)JSON.ARRTRIM 修剪數組
# 語法
# path:要指定的JSONPath。默認值是root$.
# start:是要保留的第一個元素的索引(前面的元素被修剪)。默認值為0。
# stop:是要保留的最后一個元素的索引(后面的元素被修剪),包括最后一個元素。默認值為0。負值被解釋為從末尾開始。
JSON.ARRTRIM key path start stop# 示例
127.0.0.1:6379> JSON.SET doc $ '{"name":"zhangsan","age":15,"address":"shandong","like":["sing","read","run","play"]}'
OK
127.0.0.1:6379> JSON.ARRTRIM doc $.like 1,3
(error) Couldn't parse as integer
# 修剪,保留1-3
127.0.0.1:6379> JSON.ARRTRIM doc $.like 1 3
1) (integer) 3
127.0.0.1:6379> JSON.GET doc
"{\"name\":\"zhangsan\",\"age\":15,\"address\":\"shandong\",\"like\":[\"read\",\"run\",\"play\"]}"
3、對象命令
(1)JSON.OBJKEYS 獲取所有鍵
# 語法
JSON.OBJKEYS key [path]
127.0.0.1:6379> JSON.SET doc $ '{"a":[3], "nested": {"a": {"b":2, "c": 1}}}'
OK
# 獲取指定path下所有的鍵
127.0.0.1:6379> JSON.OBJKEYS doc $..a
1) (nil)
2) 1) "b"2) "c"
(2)JSON.OBJLEN獲取鍵數
# 語法
JSON.OBJLEN key [path]# 實例
127.0.0.1:6379> JSON.SET doc $ '{"a":[3], "nested": {"a": {"b":2, "c": 1}}}'
OK
127.0.0.1:6379> JSON.OBJLEN doc $..a
1) (nil)
2) (integer) 2
4、數值操作
(1)JSON.NUMINCRBY增量操作
# 語法
# value:是要遞增的數值。
JSON.NUMINCRBY key path value
127.0.0.1:6379> JSON.SET doc . '{"a":"b","b":[{"a":2}, {"a":5}, {"a":"c"}]}'
OK
# 找不到數字,返回null
127.0.0.1:6379> JSON.NUMINCRBY doc $.a 2
"[null]"
# 遞歸進行+2操作
127.0.0.1:6379> JSON.NUMINCRBY doc $..a 2
"[null,4,7,null]"
# 對指定數值+2
127.0.0.1:6379> JSON.NUMINCRBY doc $.b[0].a 2
"[6]"
127.0.0.1:6379> JSON.GET doc
"{\"a\":\"b\",\"b\":[{\"a\":6},{\"a\":7},{\"a\":\"c\"}]}"
(2)JSON.NUMMULTBY 乘法操作
# 語法
# value 是要相乘的數值。
JSON.NUMMULTBY key path value
127.0.0.1:6379> JSON.SET doc . '{"a":"b","b":[{"a":2}, {"a":5}, {"a":"c"}]}'
OK
# 非數字的無法相乘
127.0.0.1:6379> JSON.NUMMULTBY doc $.a 2
"[null]"
# 遞歸做乘法
127.0.0.1:6379> JSON.NUMMULTBY doc $..a 2
"[null,4,10,null]"
5、字符串操作
(1)JSON.STRAPPEND字符串追加
# 語法
#value 是要追加到一個或多個字符串的值。
JSON.STRAPPEND key [path] value# 示例
redis> JSON.SET doc $ '{"a":"foo", "nested": {"a": "hello"}, "nested2": {"a": 31}}'
OK
redis> JSON.STRAPPEND doc $..a '"baz"'
1) (integer) 6
2) (integer) 8
3) (nil)
redis> JSON.GET doc $
"[{\"a\":\"foobaz\",\"nested\":{\"a\":\"hellobaz\"},\"nested2\":{\"a\":31}}]"
(2)JSON.STRLEN 獲取字符串長度
# 語法
JSON.STRLEN key [path]# 示例
redis> JSON.SET doc $ '{"a":"foo", "nested": {"a": "hello"}, "nested2": {"a": 31}}'
OK
redis> JSON.STRLEN doc $..a
1) (integer) 3
2) (integer) 5
3) (nil)
6、其他操作
(1)JSON.TYPE 獲取類型
# 語法
# 如 object, array, string 等
JSON.TYPE key [path]
redis> JSON.SET doc $ '{"a":2, "nested": {"a": true}, "foo": "bar"}'
OK
redis> JSON.TYPE doc $..foo
1) "string"
redis> JSON.TYPE doc $..a
1) "integer"
2) "boolean"
redis> JSON.TYPE doc $..dummy
(empty array)
(2)JSON.CLEAR 清除數組/對象
# 語法 清除容器值(數組/對象)并將數值設置為0
JSON.CLEAR key [path]# 示例
127.0.0.1:6379> JSON.SET doc $ '{"name":"zhangsan","age":15,"address":"shandong","like":["sing","read","run","play"]}'
OK
# 將like數組清空
127.0.0.1:6379> JSON.CLEAR doc $.like
(integer) 1
127.0.0.1:6379> JSON.GET doc
"{\"name\":\"zhangsan\",\"age\":15,\"address\":\"shandong\",\"like\":[]}"
# 對象無法清空
127.0.0.1:6379> JSON.CLEAR doc $.name
(integer) 0
127.0.0.1:6379> JSON.GET doc
"{\"name\":\"zhangsan\",\"age\":15,\"address\":\"shandong\",\"like\":[]}"
# 數值可以清空為0
127.0.0.1:6379> JSON.CLEAR doc $.*
(integer) 1
127.0.0.1:6379> JSON.GET doc
"{\"name\":\"zhangsan\",\"age\":0,\"address\":\"shandong\",\"like\":[]}"
# 根可以清空
127.0.0.1:6379> JSON.CLEAR doc $
(integer) 1
127.0.0.1:6379> JSON.GET doc
"{}"
(3)JSON.DEBUG MEMORY 查看內存
# 語法,返回一個整數,表示json占用的字節
JSON.DEBUG MEMORY key [path]# 示例
127.0.0.1:6379> JSON.SET doc $ '{"name":"zhangsan","age":15,"address":"shandong","like":["sing","read","run","play"]}'
OK
127.0.0.1:6379> JSON.DEBUG MEMORY doc
(integer) 120
(4)JSON.MERGE 合并
# 語法
JSON.MERGE key path value
value:是指定路徑中要合并的JSON值。其中的每個JSON值根據以下規則進行合并value參數,同時考慮相應的原始值(如果存在):
將現有的對象鍵與null值合并會刪除
將現有對象鍵與非空值合并會更新該值
合并不存在的對象鍵會添加鍵和值
將現有數組與任何合并值合并,用該值替換整個數組
# 合并時創建不存在的key
redis> JSON.SET doc $ '{"a":2}'
OK
redis> JSON.MERGE doc $.b '8'
OK
redis> JSON.GET doc $
"[{\"a\":2,\"b\":8}]"
# 合并時替換
redis> JSON.SET doc $ '{"a":2}'
OK
redis> JSON.MERGE doc $.a '3'
OK
redis> JSON.GET doc $
"[{\"a\":3}]"
# 合并時刪除
redis> JSON.SET doc $ '{"a":2}'
OK
redis> JSON.MERGE doc $ '{"a":null}'
OK
redis> JSON.GET doc $
"[{}]"
# 數組直接替換
redis> JSON.SET doc $ '{"a":[2,4,6,8]}'
OK
redis> JSON.MERGE doc $.a '[10,12]'
OK
redis> JSON.GET doc $
"[{\"a\":[10,12]}]"
# 多路徑合并
redis> JSON.SET doc $ '{"f1": {"a":1}, "f2":{"a":2}}'
OK
redis> JSON.GET doc
"{\"f1\":{\"a\":1},\"f2\":{\"a\":2}}"
redis> JSON.MERGE doc $ '{"f1": null, "f2":{"a":3, "b":4}, "f3":[2,4,6]}'
OK
redis> JSON.GET doc
"{\"f2\":{\"a\":3,\"b\":4},\"f3\":[2,4,6]}"
(5)JSON.TOGGLE 切換布爾值
# 語法
JSON.TOGGLE key path# 示例,切換布爾值
127.0.0.1:6379> JSON.SET doc $ '{"bool": true}'
OK
127.0.0.1:6379> JSON.TOGGLE doc $.bool
1) (integer) 0
127.0.0.1:6379> JSON.GET doc $
"[{\"bool\":false}]"
127.0.0.1:6379> JSON.TOGGLE doc $.bool
1) (integer) 1
127.0.0.1:6379> JSON.GET doc $
"[{\"bool\":true}]"