TairDoc是一种完全兼容RedisJSON的文档数据结构,支持JSON数据的增删改查。

TairDoc简介

主要特性
  • 完整地支持JSON标准。
  • 部分兼容JSONPath RFC draft-4标准。
    说明 仅JSON.GET命令支持。
  • 完整地支持JSONPointer语法。
  • 文档作为二进制树存储,可以快速访问JSON数据的子元素。
  • 支持JSON到XML或YAML格式的转换。
发布记录
  1. Tair内存型同时发布TairDoc,支持完整的JSONPointer语法与部分JSONPath语法(仅JSON.GET命令支持JSONPath语法)。
  2. 2022年5月17号发布1.8.4版,JSON.GET命令全面支持JSONPath语法,请将小版本升级至1.8.4及以上。

    该版本新增支持Dot Wild Card Selector(节点通配符选择器)、Index Selector(索引选择器)与Filter Selector(条件过滤选择器)等。

前提条件

实例为Tair(Redis企业版):
说明 最新小版本将提供更丰富的功能与稳定的服务,建议将实例的小版本升级到最新,具体操作请参见升级小版本。若实例为集群架构读写分离架构,请将代理节点的小版本也升级到最新,避免代理节点无法识别部分命令。

注意事项

操作对象为Tair实例中的TairDoc数据。

命令列表

表 1. TairDoc命令
命令 语法 说明
JSON.SET JSON.SET key path json [NX | XX]

创建key并将JSON的值存储在对应的path中,若key及目标path已经存在,则更新对应的JSON值。

JSON.GET JSON.GET key path [FORMAT XML | YAML] [ROOTNAME root] [ARRNAME arr]

获取目标key、path中存储的JSON数据。

JSON.DEL JSON.DEL key path

删除目标key中path对应的JSON数据,若未指定path,则删除key。若指定的key不存在或path不存在,则忽略。

JSON.TYPE JSON.TYPE key path

获取目标key中path对应值的类型,结果可能包括booleanstringnumberarrayobjectrawreferenceconstnull等。

JSON.NUMINCRBY JSON.NUMINCRBY key path value

对目标key中path对应的值增加value,path对应的值和待增加的value必须是int或double类型。

JSON.STRAPPEND JSON.STRAPPEND key path json-string

在指定path对应值中添加json-string字符串,path对应值的类型也需要为字符串。

JSON.STRLEN JSON.STRLEN key path

获取目标key中path对应值的字符串长度,path对应值的类型需要为字符串。

JSON.ARRAPPEND JSON.ARRAPPEND key path json [json ...]

在指定path对应数组(array)的末尾添加JSON数据,支持添加多个JSON。

JSON.ARRPOP JSON.ARRPOP key path [index]

移除并返回path对应数组(array)中指定位置(index)的元素。

JSON.ARRINSERT JSON.ARRINSERT key path [index] json [json ...]

将JSON插入到path对应的数组(array)中,原有元素会往后移动。

JSON.ARRLEN JSON.ARRLEN key path

获取path对应数组(array)的长度。

JSON.ARRTRIM JSON.ARRTRIM key path start stop

修剪目标key的path对应的数组(array),保留start至stop范围内的数据。

DEL DEL <key> [key ...] 使用原生Redis的DEL命令可以删除一条或多条TairDoc数据。
说明 本文的命令语法定义如下:
  • 大写关键字:命令关键字。
  • 斜体:变量。
  • [options]:可选参数,不在括号中的参数为必选。
  • A|B:该组参数互斥,请进行二选一或多选一。
  • ...:前面的内容可重复。

JSON.SET

类别 说明
语法 JSON.SET key path json [NX | XX]
时间复杂度

O(N)

命令描述

创建key并将JSON的值存储在对应的path中,若key及目标path已经存在,则更新对应的JSON值。

说明 若key不存在,path必须是root(即.)。
选项
  • key:TairDoc的key,用于指定作为命令调用对象的TairDoc。
  • path:目标key的path。
  • json:待新增或更新的JSON数据。
  • NX:当path不存在时写入。
  • XX:当path存在时写入。
返回值
  • 执行成功:OK。
  • 指定了XX且path不存在:nil。
  • 指定了NX且path已存在:nil。
  • 若返回ERR could not find object to add, please check path:表示您输入的path有误。
    说明 若实例的小版本为1.8.4以下,则不支持指定path$,请升级至1.8.4及以上,或将path改为root(即.)。
  • 其它情况返回相应的异常信息。
示例

命令示例:

JSON.SET doc $ '{ "store": { "book": [ { "category": "reference", "author": "Nigel Rees", "title": "Sayings of the Century", "price": 8.95 }, { "category": "fiction", "author": "Evelyn Waugh", "title": "Sword of Honour", "price": 12.99 }, { "category": "fiction", "author": "Herman Melville", "title": "Moby Dick", "isbn": "0-553-21311-3", "price": 8.99 }, { "category": "fiction", "author": "J. R. R. Tolkien", "title": "The Lord of the Rings", "isbn": "0-395-19395-8", "price": 22.99 } ], "bicycle": { "color": "red", "price": 19.95 } } }'

返回示例:

OK

JSON.GET

类别 说明
语法 JSON.GET key path [FORMAT XML | YAML] [ROOTNAME root] [ARRNAME arr]
时间复杂度

O(N)

命令描述

获取目标key、path中存储的JSON数据。

选项
  • key:TairDoc的key,用于指定作为命令调用对象的TairDoc。
  • path:目标key的path,支持JSONPath与JSON语法,按需灵活地查询,更多信息请参见JSONPath介绍JSONPointer介绍
  • FORMAT:指定返回的JSON格式,支持XML、YAML格式。
  • ROOTNAME :指定XML语法ROOT元素的标签。
  • ARRNAME:指定XML语法ARRAY元素的标签。
说明 ROOTNAME与ARRNAME参数需在指定FORMAT参数为XML时配合使用。
返回值
  • 执行成功:对应的JSON数据。
  • 其它情况返回相应的异常信息。
示例

提前执行JSON.SET doc . '{"foo": "bar", "baz" : 42}'命令。

命令示例:

JSON.GET doc . FORMAT XML ROOTNAME ROOT ARRNAME ARR

返回示例:

"<?xml version=\"1.0\" encoding=\"UTF-8\"?><ROOT><foo>bar</foo><baz>42</baz></ROOT>"

JSON.DEL

类别 说明
语法 JSON.DEL key path
时间复杂度

O(N)

命令描述

删除目标key中path对应的JSON数据,若未指定path,则删除key。若指定的key不存在或path不存在,则忽略。

选项
  • key:TairDoc的key,用于指定作为命令调用对象的TairDoc。
  • path:目标key的path。
返回值
  • 执行成功:1。
  • 执行失败:0。
  • 其它情况返回相应的异常信息。
示例

提前执行JSON.SET doc . '{"foo": "bar", "baz" : 42}'命令。

命令示例:

JSON.DEL doc .foo

返回示例:

(integer) 1

JSON.TYPE

类别 说明
语法 JSON.TYPE key path
时间复杂度

O(N)

命令描述

获取目标key中path对应值的类型,结果可能包括booleanstringnumberarrayobjectrawreferenceconstnull等。

选项
  • key:TairDoc的key,用于指定作为命令调用对象的TairDoc。
  • path:目标key的path。
返回值
  • 执行成功:返回查询到的类型。
  • 执行失败:0。
  • 若key或path不存在:nil。
  • 其它情况返回相应的异常信息。
示例

提前执行JSON.SET doc . '{"foo": "bar", "baz" : 42}'命令。

命令示例:

JSON.TYPE doc .foo

返回示例:

string

JSON.NUMINCRBY

类别 说明
语法 JSON.NUMINCRBY key path value
时间复杂度

O(N)

命令描述

对目标key中path对应的值增加value,path对应的值和待增加的value必须是int或double类型。

选项
  • key:TairDoc的key,用于指定作为命令调用对象的TairDoc。
  • path:目标key的path。
  • value:待增加的数值。
返回值
  • 执行成功:返回操作完成后path对应的值。
  • 若key或path不存在:error。
  • 其它情况返回相应的异常信息。
示例

提前执行JSON.SET doc . '{"foo": "bar", "baz" : 42}'命令。

命令示例:

JSON.NUMINCRBY doc .baz 10

返回示例:

"52"

JSON.STRAPPEND

类别 说明
语法 JSON.STRAPPEND key path json-string
时间复杂度

O(N)

命令描述

在指定path对应值中添加json-string字符串,path对应值的类型也需要为字符串。

选项
  • key:TairDoc的key,用于指定作为命令调用对象的TairDoc。
  • path:目标key的path。
  • json-string:待添加到path对应值的字符串。
返回值
  • 执行成功:返回操作完成后path对应值的字符串长度。
  • key不存在:-1。
  • 其它情况返回相应的异常信息。
示例

提前执行JSON.SET doc . '{"foo": "bar", "baz" : 42}'命令。

命令示例:

JSON.STRAPPEND doc .foo rrrrr

返回示例:

(integer) 8

JSON.STRLEN

类别 说明
语法 JSON.STRLEN key path
时间复杂度

O(N)

命令描述

获取目标key中path对应值的字符串长度,path对应值的类型需要为字符串。

选项
  • key:TairDoc的key,用于指定作为命令调用对象的TairDoc。
  • path:目标key的path。
返回值
  • 执行成功:返回path对应值的字符串长度。
  • key不存在:-1。
  • 其它情况返回相应的异常信息。
示例

提前执行JSON.SET doc . '{"foo": "bar", "baz" : 42}'命令。

命令示例:

JSON.STRLEN doc .foo

返回示例:

(integer) 3

JSON.ARRAPPEND

类别 说明
语法 JSON.ARRAPPEND key path json [json ...]
时间复杂度

O(M*N),M是需要插入的元素(json)数量,N是数组元素数量。

命令描述

在指定path对应数组(array)的末尾添加JSON数据,支持添加多个JSON。

选项
  • key:TairDoc的key,用于指定作为命令调用对象的TairDoc。
  • path:目标key的path。
  • json:需要插入的数据。
返回值
  • 执行成功:返回操作完成后数组(array)中的元素数量。
  • key不存在:-1。
  • 其它情况返回相应的异常信息。
示例

提前执行JSON.SET doc . '{"id": [1,2,3]}'命令。

命令示例:

JSON.ARRAPPEND doc .id null false true

返回示例:

(integer) 6

JSON.ARRPOP

类别 说明
语法 JSON.ARRPOP key path [index]
时间复杂度

O(M*N),M是key包含的子元素,N是数组元素数量。

命令描述

移除并返回path对应数组(array)中指定位置(index)的元素。

选项
  • key:TairDoc的key,用于指定作为命令调用对象的TairDoc。
  • path:目标key的path。
  • index:数组的索引,起始下标为0,负数表示反向取值,若不传该参数默认为最后一个元素。
返回值
  • 执行成功:移除并返回该元素。
  • 数组为空数组:‘ERR array index outflow’。
  • 其它情况返回相应的异常信息。
示例

提前执行JSON.SET doc . '{"id": [1,2,3]}'命令。

命令示例:

JSON.ARRPOP doc .id 0

返回示例:

"1"

JSON.ARRINSERT

类别 说明
语法 JSON.ARRINSERT key path [index] json [json ...]
时间复杂度

O(M*N),M是要插入的元素(json)数量,N是数组元素数量。

命令描述

将JSON插入到path对应的数组(array)中,原有元素会往后移动。

选项
  • key:TairDoc的key,用于指定作为命令调用对象的TairDoc。
  • path:目标key的path。
  • index:数组的索引,起始下标为0,负数表示反向取值,若不传该参数默认为最后一个元素。
  • json:需要插入的数据。
返回值
  • 执行成功:返回操作完成后数组(array)中的元素数量。
  • 数组为空数组:‘ERR array index outflow’。
  • 其它情况返回相应的异常信息。
示例

提前执行JSON.SET doc . '{"id": [1,2,3]}'命令。

命令示例:

JSON.ARRINSERT doc .id 0 10 15

返回示例:

(integer) 5

JSON.ARRLEN

类别 说明
语法 JSON.ARRLEN key path
时间复杂度

O(N)

命令描述

获取path对应数组(array)的长度。

选项
  • key:TairDoc的key,用于指定作为命令调用对象的TairDoc。
  • path:目标key的path。
返回值
  • 执行成功:数组(array)的长度。
  • key不存在:-1。
  • 其它情况返回相应的异常信息。
示例

提前执行JSON.SET doc . '{"id": [1,2,3]}'命令。

命令示例:

JSON.ARRLEN doc .id

返回示例:

(integer) 3

JSON.ARRTRIM

类别 说明
语法 JSON.ARRTRIM key path start stop
时间复杂度

O(N)

命令描述

修剪目标key的path对应的数组(array),保留start至stop范围内的数据。

选项
  • key:TairDoc的key,用于指定作为命令调用对象的TairDoc。
  • path:目标key的path。
  • start:修剪的开始位置,取值为从0开始的一个索引值,修剪后的数组包含该位置的元素。
  • stop:修剪的结束位置,取值为从0开始的一个索引值,修剪后的数组包含该位置的元素。
返回值
  • 执行成功:返回操作完成后数组的长度。
  • key不存在:-1。
  • 其它情况返回相应的异常信息。
示例

提前执行JSON.SET doc . '{"id": [1,2,3,4,5,6]}'命令。

命令示例:

JSON.ARRTRIM doc .id 3 4

返回示例:

(integer) 2

JSONPath介绍

TairDoc支持JSONPath的兼容语法如下表所示:

JSONPath 说明
$ 根元素。
@ 当前元素。
.name 子元素。
.. 任意位置符合要求的元素。
* 通配符,表示所有子元素或数组元素。
[ ] 数组索引,索引从0开始,例如[0];支持选择列表,例如[0,1],表示0和1;也支持添加元素名,例如['name']。
[start:end:step] 数组切片选择器(Array Slice Selector),表示从start开始,到end结束,按照step为步长来获取元素,例如[0:3:1],表示从第0位到第3位。若步长为负数,则从后向前获取。
?... 条件过滤选择器。
() 支持表达式,优先级为:( ) > && > ||,更多信息,请参见JSONPath
查询示例
  1. 创建JSON文档。

    命令实例:

    JSON.SET dockey $
    '{
        "store": {
            "book": [{
                    "category": "reference",
                    "author": "Nigel Rees",
                    "title": "Sayings of the Century",
                    "price": 8.95
                },
                {
                    "category": "fiction",
                    "author": "Evelyn Waugh",
                    "title": "Sword of Honour",
                    "price": 12.99
                },
                {
                    "category": "fiction",
                    "author": "Herman Melville",
                    "title": "Moby Dick",
                    "isbn": "0-553-21311-3",
                    "price": 8.99
                },
                {
                    "category": "fiction",
                    "author": "J. R. R. Tolkien",
                    "title": "The Lord of the Rings",
                    "isbn": "0-395-19395-8",
                    "price": 22.99
                }
            ],
            "bicycle": {
                "color": "red",
                "price": 19.95
            }
        },
        "expensive": 10
    }'

    预计返回:

    OK
  2. 查询文档。

    查询示例如下:

    # 查询整个JSON对象。
    JSON.GET dockey $
    
    # 预期输出:
    "[{"store":{"book":[{"category":"reference","author":"Nigel Rees","title":"Sayings of the Century","price":8.95},{"category":"fiction","author":"Evelyn Waugh","title":"Sword of Honour","price":12.99},{"category":"fiction","author":"Herman Melville","title":"Moby Dick","isbn":"0-553-21311-3","price":8.99},{"category":"fiction","author":"J. R. R. Tolkien","title":"The Lord of the Rings","isbn":"0-395-19395-8","price":22.99}],"bicycle":{"color":"red","price":19.95}}}]"
    # 查询store中bicycle的所有信息。
    JSON.GET dockey $.store.bicycle.*
    
    # 预期输出:
    "["red",19.95]"
    
    # 查询store中bicycle的price信息。
    JSON.GET dockey $.store.bicycle.price
    
    # 预期输出:
    "[19.95]"
    # 查询store中第一本book的所有信息。
    JSON.GET dockey $.store.book[0]
    
    # 预期输出:
    "[{"category":"reference","author":"Nigel Rees","title":"Sayings of the Century","price":8.95}]"
    
    # 查询store中所有book的title信息。
    JSON.GET dockey "$.store.book[*]['title']"
    
    # 预期输出:
    "["Sayings of the Century","Sword of Honour","Moby Dick","The Lord of the Rings"]"
    # 使用数组分片的方式查询book中第1至第3本书的所有信息,步长为1。
    JSON.GET dockey $.store.book[0:2:1]
    
    # 预期输出:
    "[{"category":"reference","author":"Nigel Rees","title":"Sayings of the Century","price":8.95},{"category":"fiction","author":"Herman Melville","title":"Moby Dick","isbn":"0-553-21311-3","price":8.99},{"category":"fiction","author":"Evelyn Waugh","title":"Sword of Honour","price":12.99}]"
    # 查询store中所有price信息,包含book和bicycle的price信息。
    JSON.GET dockey $..price
    
    # 预期输出:
    "[8.95,12.99,8.99,22.99,19.95]"
    # # 查询store中第一本和第三本book的所有信息。
    JSON.GET dockey $.store.book[0,2]
    
    # 预期输出:
    "[{"category":"reference","author":"Nigel Rees","title":"Sayings of the Century","price":8.95},{"category":"fiction","author":"Herman Melville","title":"Moby Dick","isbn":"0-553-21311-3","price":8.99}]"
    # @表达式
    # 查询store中book中包含isbn元素的信息。
    JSON.GET dockey $.store.book[?(@.isbn)]
    # 预期输出:
    "[{"category":"fiction","author":"Herman Melville","title":"Moby Dick","isbn":"0-553-21311-3","price":8.99},{"category":"fiction","author":"J. R. R. Tolkien","title":"The Lord of the Rings","isbn":"0-395-19395-8","price":22.99}]"
    
    
    # COMP表达式
    # 查询store中price小于10的book信息。
    JSON.GET dockey '$.store.book[?(@.price < 10)]'
    # 预期输出:
    "[{"category":"reference","author":"Nigel Rees","title":"Sayings of the Century","price":8.95},{"category":"fiction","author":"Herman Melville","title":"Moby Dick","isbn":"0-553-21311-3","price":8.99}]"
    
    # 组合表达式
    # 查询目标book信息,条件为price为12.99或者price比bicycle的price贵或者category为reference。
    JSON.GET dockey "$..book[?((@.price == 12.99 || @.price > $.store.bicycle.price) || @.category == 'reference')]"
    # 预期输出:
    "[{"category":"reference","author":"Nigel Rees","title":"Sayings of the Century","price":8.95},{"category":"fiction","author":"J. R. R. Tolkien","title":"The Lord of the Rings","isbn":"0-395-19395-8","price":22.99},{"category":"fiction","author":"Evelyn Waugh","title":"Sword of Honour","price":12.99}]"

JSONPointer介绍

TairDoc支持完整的JSONPointer语法,更多信息,请参见JavaScript Object Notation (JSON) Pointer

示例如下。

提前执行JSON.SET doc . '{"foo": "bar", "baz" : [1,2,3]}'命令。

命令示例:

# 获取doc中.baz的第一个值。
JSON.GET doc /baz/0

返回示例:

"1"