1. 程式人生 > 其它 >【深入理解TcaplusDB技術】陣列操作介紹

【深入理解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和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]);
}

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級儲存、毫秒級時延、無損水平擴充套件和複雜資料結構等特性。同時具備豐富的生態、便捷的遷移、極低的運維成本和五個九高可用等特點。客戶覆蓋遊戲、網際網路、政務、金融、製造和物聯網等領域。