【TcaplusDB知识库】如何对数组进行操作
2023-03-14 22:58:19 时间
【TcaplusDB知识库】如何对数组进行操作
为了支持对数组的灵活操作,即 protobuf 中 repeated 字段,类似 Redis 中对 list、set 等数据结构的操作能力,TcaplusDB 提供对数组的命令式的操作。具备如下能力:
- PUSH 操作:在数组指定位置插入新的元素数据。
- SET 操作:修改数组指定位置的元素数据。
- POP 操作:删除数组中某些下标范围或者满足某些条件的元素。
- GET 查询:指定记录的 key,查询数组返回数组中某些下标范围或者满足某些条件的元素(即仅记录的局部数据)。
4.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);
4.2 使用示例
这里列举几个使用示例,数组操作的详细语法见下一小节,更多示例见 example。
4.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]");
4.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和2
int 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]);
}
4.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级存储、毫秒级时延、无损水平扩展和复杂数据结构等特性。同时具备丰富的生态、便捷的迁移、极低的运维成本和五个九高可用等特点。客户覆盖游戏、互联网、政务、金融、制造和物联网等领域。
相关文章
- 数据孤岛是业务效率的无声杀手
- 2023展望:新的一年将给大数据分析领域带来什么?
- 阿里云ADB基于Hudi构建Lakehouse的实践
- 大数据在医疗保健领域的使用案例
- 微软增加说明:KB5021751 更新扫描已经 / 即将过时 Office 过程中不会触碰用户隐私
- 2022 Gartner全球云数据库管理系统魔力象限发布 腾讯云数据库入选
- 场景化、重实操,分享一个实时数仓实践案例
- Arctic的湖仓一体践行之路
- 分布式计算MapReduce究竟是怎么一回事?
- 淘系数据模型治理优秀实践
- 大数据分析对医疗保健的影响
- 当我们说大数据Hadoop,究竟在说什么?
- 2022年及以后大数据的五个发展趋势
- 网易严选离线数仓治理实践
- 2023 年数据治理趋势
- 一份“靠谱”的年度经营计划,你学会了吗?
- 漫谈对大数据的思考
- 测试一下,读懂数据的能力,你有吗?
- 用艺术的眼光探索数据之美
- 聊聊数据分析成果如何落地