部分字段查询和更新

Pb对象是嵌套树结构,完整的Pb message可能会较大,tcaplus可支持对部分字段或嵌套字段的查询和更新,如"timekey", "pay.order.desc", "str_map['key'].desc"。

示例表

message tb_online3 {
    option(tcaplusservice.tcaplus_primary_key) = "openid";

    message order_info {
        int32 oid = 1;
        string desc = 2;
    }

    message pay_info {
        double total_money = 1;
        uint64 pay_times = 2;
        order_info order = 3;

        int32 pid = 4;
        string desc = 5;
    }

    int32 openid = 1;
    uint32 tconndid = 2;
    string timekey = 3;
    repeated int64 lockid = 4;
    pay_info pay = 5;
    repeated pay_info pay_array = 6;
    repeated string desc_array = 7;

    map<int32, all_type_t> int_map = 9;
    map<string, all_type_t> str_map = 10;

    map<string, string> str_str = 11;
}

部分字段查询

Pb表支持部分字段更新,见FieldGet接口,大致参数如下:

  • 入参&出参:pb message,message中的key,作为输入;查询成功之后,返回的数据会回填到这个message中作为输出。
  • 入参:field_paths,指定的要更新的字段集合,如{"timekey", "pay.order.desc", "str_map['key'].desc"}。
  • 入参:condition,条件过滤,仅当条件满足时才返回,否则会返回条件不匹配的错误码COMMON_ERR_CONDITION_NOT_MATCHED

支持以下类型的字段:

  • 一级字段,如"timekey"、"pay"、"desc_array"。
  • 嵌套字段,如"pay.order.desc"。
  • Map的元素的嵌套字段,如"int_map[1001]"、"str_str['key'],对于"str_map['key'].desc",若map的key不存在则报错COMMON_ERR_ELEMENT_NOT_EXIST
  • 数组的嵌套字段,如"pay_array[0]"、"pay_array[0].order.desc",若数组下标不存在则报错。
  • 数组范围,如"pay_array[0-100]"、"pay_array[0- -1]",其中-1表示直到末尾。
  • 一趟请求,可支持对多个字段进行查询,如{"timekey", "pay.order.desc", "str_map['key'].desc"}。
  • 但是多字段不能有路径重叠,如{"pay", "pay.order.desc"},可能得不到预期结果。

字段路径的总结,使用点号(.)表示嵌套字段,使用方括号([])表示数组索引和map key,不支持路径中使用多个方括号([]),如"map['key'].a.sub_map['sub_key']"。

部分字段更新

Pb表支持部分字段更新,见C++ SDK的FieldSet接口,Go SDK的FieldUpdate接口。

FieldSetFieldUpdate的行为如下:

  • 入参&出参:pb message,message中的key和包含的增量数据,作为输入;更新成功之后,返回的数据会回填到这个message中。
  • 入参:field_paths,指定的要更新的字段集合,如{"timekey", "pay.order.desc", "str_map['key'].desc"}。
  • 入参:operation,额外捎带的文本描述的操作,如"pay.pay_times += 1"。
  • 入参:condition,条件过滤,仅当条件满足时才更新,否则会返回条件不匹配的错误码COMMON_ERR_CONDITION_NOT_MATCHED

部分字段更新,支持以下这些类型的字段:

  • 一级字段的更新,如"timekey"、"pay"、"desc_array"。
  • 嵌套字段,如"pay.order.desc"。
  • Map的元素的嵌套字段,如"int_map[1001]"、"str_map['key'].desc"、"str_str['key'],若map的key不存在则创建之。
  • Map元素的插入,如"PUSH int_map[1001]",若map的key已存在则报错。
  • Map元素的删除,如"POP int_map[1001]",若map的key不存在,也会返回成功。
  • 一趟请求,可支持对多个字段进行更新,会同时生效,如{"timekey", "pay.order.desc", "str_map['key'].desc"}。
  • 但是多字段更新不能有路径重叠,如{"pay", "pay.order.desc"},不会报错,但因为更新顺序问题可能得不到预期结果。

因为对Map元素的更新,可以支持一种类Schema-free的用法,见《Schema-free》。

不支持像map元素一样,对数组元素的更新(即repeated字段):

  • 不支持数组元素的嵌套字段,如"pay_array[0]"、"pay_array[0].desc",只支持数组字段的整体更新(即"pay_array")。
  • 若要更新数组,只能通过operation语句对数组元素进行PUSH、SET、POP操作,文本语法见《条件过滤和更新语法说明》,能力与限制见《条件过滤和更新功能》。

字段路径的总结,使用点号(.)表示嵌套字段,使用方括号([])表示map key(不支持数组索引),不支持路径中使用多个方括号([]),如"map['key'].a.sub_map['sub_key']"。

记录不存在时创建

默认,当修改的记录不存在时,会报错TXHDB_ERR_RECORD_NOT_EXIST。 若希望记录不存在时,自动创建,可通过接口SetMessageOption设置。

C++SDK相关接口:

    /**
    *    i).MESSAGE_OPTION_ENABLE_SET_NOT_EXIST = 9, API中设置允许FieldSet操作不存在的记录时创建之,取值0不允许,取值1允许
    */
    int SetMessageOption(const ::google::protobuf::Message &msg, int32_t item, const std::string &option);

GoSDK相关接口:

const (
    TcaplusFlagInsertRecordIfNotExist           int32 = 16 //PB的FieldUpdate使用,数据不存在则插入
)

func (req *pbFieldUpdateRequest) SetFlags(flag int32) int

ResultFlag

更新返回之后,默认总是把请求的key和增量数据回填到原message(入参&出参)。 而有些场景下,需要返回其他数据,如更新前的旧数据,接口SetMessageOption支持设置返回数据。

C++SDK相关接口:

    /**
    *    j).MESSAGE_OPTION_RESULT_FLAG_FOR_SUCCESS = 10, 用户显式设置请求执行成功时的响应标志,会覆盖API的默认配置
    *       option取值有    "0":表示只需返回操作执行成功与否
    *                       "1":表示返回与请求字段一致
    *                       "2":表示须返回变更记录的所有字段最新数据
    *                       "3":表示须返回变更记录的所有字段旧数据
    *       其中,对于FieldSet操作,不设置该选项,总是返回和请求一致的数据
    *    k).MESSAGE_OPTION_RESULT_FLAG_FOR_FAIL = 11, 用户显式设置请求执行失败时的响应标志,会覆盖API的默认配置
    *       option取值有    "0":表示只需返回操作执行成功与否
    *                       "1":表示返回与请求字段一致
    *                       "2":表示须返回变更记录的所有字段最新数据
    *                       "3":表示须返回变更记录的所有字段旧数据
    *       其中,对于FieldSet操作,不设置该选项,总是返回和请求一致的数据
    */
    int SetMessageOption(const ::google::protobuf::Message &msg, int32_t item, const std::string &option);

GoSDK相关接口:

const (
    TcaplusResultFlagNoValue         byte = 0
    TcaplusResultFlagSameWithRequest byte = 1
    TcaplusResultFlagAllNewValue     byte = 2
    TcaplusResultFlagAllOldValue     byte = 3
)

func (req *pbFieldUpdateRequest) SetResultFlagForSuccess(result_flag byte) int
func (req *pbFieldUpdateRequest) SetResultFlagForFail(result_flag byte) int

当option取值2、3时,返回的是记录的所有字段数据(非部分修改字段),若完整记录数据较大时,高频操作会占用较大的网路带宽。

results matching ""

    No results matching ""