写点什么

【深入理解 TcaplusDB 技术】数组操作介绍

作者:数据人er
  • 2022 年 5 月 16 日
  • 本文字数:2762 字

    阅读完需:约 9 分钟

【深入理解TcaplusDB技术】数组操作介绍

【深入理解 TcaplusDB 技术】数组操作介绍

为了支持对数组的灵活操作,即 protobuf 中 repeated 字段,类似 Redis 中对 list、set 等数据结构的操作能力,TcaplusDB 提供对数组的命令式的操作。具备如下能力:


  • PUSH 操作:在数组指定位置插入新的元素数据。

  • SET 操作:修改数组指定位置的元素数据。

  • POP 操作:删除数组中某些下标范围或者满足某些条件的元素。

  • GET 查询:指定记录的 key,查询数组返回数组中某些下标范围或者满足某些条件的元素(即仅记录的局部数据)。

1 接口介绍

支持的 PUSH、SET、POP 操作 使用 UpdateItem 接口,支持的 Get 使用 Query 接口,其中 generic 表的 coroutine 接口定义如下:


// 入参/出参 msg:包含用户输入的key值,返回修改后的数据也填入到msg// 入参 operation:数组操作语句,即PUSH、SET、POP// 入参 condition:记录的过滤条件int UpdateItem(::google::protobuf::Message *msg, const std::string &operation, const std::string &condition = "");
// 入参/出参 msg:包含用户输入的key值,返回查询的局部数据也填入到msg,注意,返回的msg会和输入的msg合并,相当于接口内部调用Message::MergeFrom// 入参 operation:数组查询语句,即GET// 入参 queryOption:查询选项,当前仅支持通过TCAPLUS_PB_API_QUERY_RETURN_ARRAY_INDEX指定是否需要返回查询数组元素的原始下标// 入参 condition:记录的过滤条件// 出参 vecArrayIndex:若指定TCAPLUS_PB_API_QUERY_RETURN_ARRAY_INDEX,返回查询数组元素的原始下标int Query(::google::protobuf::Message *msg, const std::string &query, int queryOption, const std::string &condition, std::vector<int> &vecArrayIndex);
复制代码

2 使用示例

这里列举几个使用示例,数组操作的详细语法见下一小节,更多示例见 example。

2.1 数组更新示例

user u;// 设置主键u.set_id(1);u.set_name("a");
// 在mailbox数组尾部插入一个元素(同时对元素内的title等字段赋值),这里-1表示尾部的数组下标int ret = api.UpdateItem(&u, "PUSH mailbox #[-1] [title = \"tcaplus\", content = \"...\"]");
// 当gameids数组不包含101时,在gameids数组头部插入一个元素101,这里0表示头部的数组下标,$表示当前操作的数组元素// 注意,这里还多了第三个参数,即条件过滤,仅当条件满足时,才执行push操作ret = api.UpdateItem(&u, "PUSH gameids #[0] [$ = 101]", "gameids NOT CONTAINS($ == 101)");
// 删除mailbox数组下标0 ~ 10范围内,且title不等于"tcaplus"的元素ret = api.UpdateItem(&u, "POP mailbox #[0-10] [title != \"tcaplus\"]");
// 修改指定下标为1的元素ret = api.UpdateItem(&u, "SET gameids #[1] [$ = 101]");
复制代码

2.2 数组查询示例

user u;// 设置主键u.set_id(1);u.set_name("a");
// 假设服务端user.mailbox包含4个元素,为// [ { "tcaplus", "..." }, { "not-tcaplus", "..." }, { "tcaplus", "..." }, { "not-tcaplus", "..." } ]
// 查询mailbox数组下标为0 ~ 2且title为"tcaplus"的元素// 这里仅返回局部数据,即两个数组元素,并填入u中,也就是说u既作为入参(提供主键),也是出参(包含返回的局部数据)// option设置TCAPLUS_PB_API_QUERY_RETURN_ARRAY_INDEX时,则也会返回这两个元素的下标,即0和2int option = 0;option |= TCAPLUS_PB_API_QUERY_RETURN_ARRAY_INDEX;std::vector<int> vecArrayIndex;ASSERT_EQ(0, u.mailbox_size());int ret = api.Query(&u, "GET mailbox #[0-2] [title == \"tcaplus\"]", option, "", vecArrayIndex);if (ret == 0) { ASSERT_EQ(2, u.mailbox_size()); ASSERT_EQ(0, vecArrayIndex[0]); ASSERT_EQ(2, vecArrayIndex[1]);}
复制代码

3 语法说明

PUSH 和 SET 语法一样,只有语义上的差异,前者在指定位置插入,后者在指定位置原地修改。


PUSH 和 SET 语法由 3 部分组成,即 数组字段名称 + 下标 + 若干个赋值表达式。其中当元素是组合类型,是各个字段的赋值,当元素是基本类型,使用$引用当前元素进行赋值。


POP 的语法由 3 部分组成,即 数组字段名称 + 下标范围 + 嵌套的过滤条件,后两个是可选的。 和 PUSH 不同,POP 可以某些下标范围而不仅仅是单个下标,这里过滤条件的语法和上一章节记录的过滤条件一样,区别是过来条件的上下文不一样,这里的是元素的数据,而另一个是整个记录的数据。


GET 的语法和 POP 一样。


完整的操作语法如下


push_expr ::=    PUSH array # '[' index ']' '[' assign_expr [, assign_expr]* ']'
set_expr ::= SET array # '[' index ']' '[' assign_expr[, assign_expr]* ']'
pop_expr ::= POP array | POP array # '[' index_range ']' | POP array # '[' index_range ']' '[' condition ']'
get_expr ::= GET array | GET array # '[' index_range ']' | GET array # '[' index_range ']' '[' condition ']'
assign_expr ::= identifier = number | string | $ = number | string
index ::= integer
index_range ::= index [, index_range]* | index - index [, index_range]*
复制代码


  • 语法说明

  • assign_expr: 赋值表达式,若数组元素是组合类型,则是内部字段的赋值title = \"tcaplus\", content = \"...\",若元素是基本类型,则使用$引用元素本身,如$=101

  • index: 数组的下标,其中 0 表示数组头部下标,在不知道数组大小情况下,使用-1 表示尾部的下标。

  • index_range: 数组下标范围,如 "0 - -1" 表示所有的下标,也可以表示多个不连续的范围,如 "0 - 8, -1"。

  • condition: 嵌套的过滤条件,语法和上一章节记录的条件过滤一致,区别在于,前者的语义上下文是整个记录的数据,这里的是数组元素中的数据。

  • PUSH/SET 的说明

  • 赋值表达式中,当前只支持对整型、浮点、字符串类型的字段赋值,且必须非 repeated 类型,若 repeated 字段本身是基本类型,则使用$引用的元素自身。

  • 赋值表达式中,不同类型整型、浮点型可以相互赋值,即会进行类型强转,有可能出现截断等情况,类型转换的行为和 C++中一致。

  • 对于 SET,若数组大小为 N,下标的有效范围是 0 ~ (N - 1)或-1。

  • 对于 PUSH,若数组大小为 N,下标的有效范围是 0 ~ N 或-1。

  • POP 的说明

  • POP,删除某些范围或某些满足条件的元素。

  • 基于 删除不存在的元素不会报错 的原则,pop 指定一个不存在的下标范围时,不会报错,例如数组大小为 10,8-80会删除最后 2 个元素。





TcaplusDB 是腾讯出品的分布式 NoSQL 数据库,存储和调度的代码完全自研。具备缓存+落地融合架构、PB 级存储、毫秒级时延、无损水平扩展和复杂数据结构等特性。同时具备丰富的生态、便捷的迁移、极低的运维成本和五个九高可用等特点。客户覆盖游戏、互联网、政务、金融、制造和物联网等领域。

用户头像

数据人er

关注

还未添加个人签名 2021.03.09 加入

还未添加个人简介

评论

发布
暂无评论
【深入理解TcaplusDB技术】数组操作介绍_数据库_数据人er_InfoQ写作社区