Doc

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内存型

说明

最新小版本将提供更丰富的功能与稳定的服务,建议将实例的小版本升级到最新,具体操作请参见升级小版本。如果您的实例为集群架构或读写分离架构,请将代理节点的小版本也升级到最新,否则可能出现命令无法识别的情况。

注意事项

操作对象为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.MERGE

JSON.MERGE key path value

将value的Json合并到指定Key的path路径中。可对目标路径下的值实现新增、更新、删除等操作。

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: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有误。

  • 其它情况返回相应的异常信息。

示例

命令示例:

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.MERGE

类别

说明

语法

JSON.MERGE key path value

时间复杂度

O(N)

命令描述

将value的Json合并到指定Key的path路径中。可对目标路径下的值实现新增、更新、删除等操作。

选项

  • key:TairDoc的Key,用于指定作为命令调用对象的TairDoc。

  • path:目标Key的path,支持部分JSONPath语法,例如$.a.b.c$.a['b'],但不支持$..$*等复杂表达式。

  • value:待合并的Json,格式兼容Json Merge Patch RFC7386

返回值

  • 执行成功:OK。

  • 若value有误:parse merge patch error。

  • 其它情况返回相应的异常信息。

示例

提前执行JSON.SET doc $ '{"f1": {"a":1}, "f2":{"a":2}}'命令。

命令示例:

JSON.MERGE doc $ '{"f1": null, "f2":{"a":3, "b":4}, "f3":[2,4,6]}'

返回示例:

OK

此时,执行JSON.GET doc .的结果如下:

"{\"f2\":{\"a\":3,\"b\":4},\"f3\":[2,4,6]}"

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. 查询文档。

    查询示例如下:

    Root Selector

    # 查询整个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}}}]"

    Dot Selector

    # 查询store中bicycle的所有信息。
    JSON.GET dockey $.store.bicycle.*
    
    # 预期输出:
    "["red",19.95]"
    
    # 查询store中bicycle的price信息。
    JSON.GET dockey $.store.bicycle.price
    
    # 预期输出:
    "[19.95]"

    Index Selector

    # 查询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"]"

    Array Slice Selector

    # 使用数组分片的方式查询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}]"

    Descendant Selector

    # 查询store中所有price信息,包含book和bicycle的price信息。
    JSON.GET dockey $..price
    
    # 预期输出:
    "[8.95,12.99,8.99,22.99,19.95]"

    List Selector

    # # 查询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}]"

    Filter Selector

    # @表达式
    # 查询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"