【TcaplusDB知識庫】如何對陣列進行操作

zmgogo 發表於 2021-11-23


為了支援對陣列的靈活操作,即 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 個元素。


img

TcaplusDB是騰訊出品的分散式NoSQL資料庫,儲存和排程的程式碼完全自研。具備快取+落地融合架構、PB級儲存、毫秒級時延、無損水平擴充套件和複雜資料結構等特性。同時具備豐富的生態、便捷的遷移、極低的運維成本和五個九高可用等特點。客戶覆蓋遊戲、網際網路、政務、金融、製造和物聯網等領域。



來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69982264/viewspace-2843734/,如需轉載,請註明出處,否則將追究法律責任。