进阶指南
一、发送事件
在 SDK 初始化完成之后,您就可以进行数据埋点,收集用户的的行为信息。一般情况下普通事件即可满足业务场景需求,您也可以根据自己的实际业务场景使用首次、可更新等事件。
1.1 普通事件
您可以调用 td_track 来上传事件,建议您根据先前梳理的文档来设置事件的属性以及发送事件的条件,此处以用户购买某商品作为范例:
// 设置事件属性
TDProperties *properties = td_init_properties();
TD_ASSERT(TD_OK == td_add_string("product_name", "goods_name", strlen("goods_name"), properties));
// 上报带有自定义属性的事件数据,同样account_id 和 distinct_id 必须至少设置其中一个
TD_ASSERT(TD_OK == td_track("account_id", "distinct_id", "product_buy", properties, ta));
td_free_properties(properties);
1.2 首次事件
首次事件是指针对某个设备或者其他维度的 ID,只会记录一次的事件。例如在一些场景下,您可能希望记录在某个设备上的激活事件,则可以用首次事件来上报数据。
TD_ASSERT(TD_OK == td_track_first_event("account_id", "distinct_id", "device_activation", "first_id", properties, ta));
注意:由于在服务端完成对是否首次的校验,首次事件默认会延时 1 小时入库。
1.3 可更新事件
您可以通过可更新事件实现特定场景下需要修改事件数据的需求。可更新事件需要指定标识该事件的 ID,并在创建可更新事件对象时传入。AE 后台将根据事件名和事件 ID 来确定需要更新的数据。
// 上报可更新事件,事件名为UPDATABLE_EVENT,事件ID为event_id
// 上报后事件属性 status 为 3, price 为 100
TDProperties *properties = td_init_properties();
TD_ASSERT(TD_OK == td_add_int("price",100,properties));
TD_ASSERT(TD_OK == td_add_int("status",3,properties));
TD_ASSERT(TD_OK == td_track_update("account_id", "distinct_id", "UPDATABLE_EVENT", "event_id",properties, ta));
td_free_properties(properties);
// 上报后同样的事件属性 status 被更新为 5, price 不变
TDProperties *new_properties = td_init_properties();
TD_ASSERT(TD_OK == td_add_int("status",5,new_properties));
TD_ASSERT(TD_OK == td_track_update("account_id", "distinct_id", "UPDATABLE_EVENT", "event_id",new_properties, ta));
td_free_properties(new_properties);
1.4 可重写事件
可重写事件与可更新事件类似,区别在于可重写事件会用最新的数据完全覆盖历史数据,从效果上看相当于删除前一条数据,并入库最新的数据。AE 后台将根据事件名和事件 ID 来确定需要更新的数据。
// 上报可重写事件,事件名为OVERWRITE_EVENT,事件ID为event_id
// 上报后事件属性 status 为 3, price 为 100
TDProperties *properties = td_init_properties();
TD_ASSERT(TD_OK == td_add_int("price",100,properties));
TD_ASSERT(TD_OK == td_add_int("status",3,properties));
TD_ASSERT(TD_OK == td_track_overwrite("account_id", "distinct_id", "OVERWRITE_EVENT", "event_id",properties, ta));
td_free_properties(properties);
// 上报后同样的事件属性 status 被更新为 5, price 属性被删除
TDProperties *new_properties = td_init_properties();
TD_ASSERT(TD_OK == td_add_int("status",5,new_properties));
TD_ASSERT(TD_OK == td_track_overwrite("account_id", "distinct_id", "OVERWRITE_EVENT", "event_id",new_properties, ta));
td_free_properties(new_properties);
二、用户属性
AE 平台支持的用户属性设置API有: td_user_set、td_user_setOnce、td_user_add、td_user_unset、td_user_delete、td_user_append、td_user_uniq_append。
2.1 td_user_set
对于一般的用户属性,您可以调用td_user_set来进行设置。使用该接口上传的属性将会覆盖原有的属性值,如果之前不存在该用户属性,则会新建该用户属性,类型与传入属性的类型一致,此处以设置用户名为例:
//此时user_name为TA
TDProperties *user_properties = td_init_properties();
TD_ASSERT(TD_OK == td_add_string("user_name", "TA", strlen("TA"), user_properties));
TD_ASSERT(TD_OK == td_user_set("account_id", "distinct_id", user_properties,ta));
td_free_properties(user_properties);
//此时user_name为AE
TDProperties *user_properties2 = td_init_properties();
TD_ASSERT(TD_OK == td_add_string("user_name", "AE", strlen("AE"), user_properties2));
TD_ASSERT(TD_OK == td_user_set("account_id", "distinct_id", user_properties2,ta));
td_free_properties(user_properties2);
2.2 td_user_setOnce
如果您要上传的用户属性只要设置一次,则可以调用td_user_setOnce来进行设置,当该属性之前已经有值的时候,将会忽略这条信息,以设置首次付费时间为例:
//first_payment_time为2018-01-01 01:23:45.678
TDProperties *user_properties = td_init_properties();
TD_ASSERT(TD_OK == td_add_string("first_payment_time", "2018-01-01 01:23:45.678", strlen("2018-01-01 01:23:45.678"), user_properties));
TD_ASSERT(TD_OK == td_user_setOnce("account_id", "distinct_id", user_properties,ta));
td_free_properties(user_properties);
//first_payment_time仍然为2018-01-01 01:23:45.678
TDProperties *user_properties2 = td_init_properties();
TD_ASSERT(TD_OK == td_add_string("first_payment_time", "2018-12-31 01:23:45.678", strlen("2018-12-31 01:23:45.678"), user_properties2));
TD_ASSERT(TD_OK == td_user_setOnce("account_id", "distinct_id", user_properties2,ta));
td_free_properties(user_properties2);
2.3 td_user_add
当您要上传数值型的属性时,您可以调用td_user_add来对该属性进行累加操作,如果该属性还未被设置,则会赋值 0 后再进行计算,可传入负值,等同于相减操作。此处以累计付费金额为例:
// 上传用户属性,此时"total_revenue"的值为30
TDProperties *user_properties = td_init_properties();
TD_ASSERT(TD_OK == td_add_int("total_revenue", 30, user_properties));
TD_ASSERT(TD_OK == td_user_add("account_id", "distinct_id", user_properties, ta));
td_free_properties(user_properties);
// 上传用户属性,此时"total_revenue"的值为678
TDProperties *new_user_properties = td_init_properties();
TD_ASSERT(TD_OK == td_add_int("total_revenue",648 , new_user_properties));
TD_ASSERT(TD_OK == td_user_add("account_id", "distinct_id", new_user_properties, ta));
td_free_properties(new_user_properties);
设置的属性key为字符串,Value 只允许为数值。
2.4 td_user_append
您可以调用 td_user_append 对数组类型的用户属性进行追加操作。
// 此时user_list的属性值为["apple","ball"]
TDProperties *array_properties = td_init_properties();
TD_ASSERT(TD_OK == td_append_array("user_list", "apple", strlen("apple"), array_properties));
TD_ASSERT(TD_OK == td_append_array("user_list", "ball", strlen("ball"), array_properties));
TD_ASSERT(TD_OK == td_user_append("account_id", "distinct_id", array_properties, ta));
td_free_properties(array_properties);
// 此时user_list的属性值为["apple","apple","ball","cube"]
TDProperties *new_array_properties = td_init_properties();
TD_ASSERT(TD_OK == td_append_array("user_list", "apple", strlen("apple"), new_array_properties));
TD_ASSERT(TD_OK == td_append_array("user_list", "cube", strlen("cube"), new_array_properties));
TD_ASSERT(TD_OK == td_user_append("account_id", "distinct_id", new_array_properties, ta));
td_free_properties(new_array_properties);
2.5 td_user_uniq_append
您可以调用 td_user_uniq_append 对 数组类型的用户属性进行追加操作。调用 td_user_uniq_append 接口会对追加的用户属性进行去重, td_user_append 接口不做去重,用户属性可存在重复。
// 此时user_list的属性值为["apple","ball"]
TDProperties *array_properties = td_init_properties();
TD_ASSERT(TD_OK == td_append_array("user_list", "apple", strlen("apple"), array_properties));
TD_ASSERT(TD_OK == td_append_array("user_list", "ball", strlen("ball"), array_properties));
TD_ASSERT(TD_OK == td_user_append("account_id", "distinct_id", array_properties, ta));
td_free_properties(array_properties);
// 此时user_list的属性值为["apple","ball","cube"]
TDProperties *new_array_properties = td_init_properties();
TD_ASSERT(TD_OK == td_append_array("user_list", "apple", strlen("apple"), new_array_properties));
TD_ASSERT(TD_OK == td_append_array("user_list", "cube", strlen("cube"), new_array_properties));
TD_ASSERT(TD_OK == td_user_uniq_append("account_id","distinct_id", new_array_properties, ta));
td_free_properties(new_array_properties);
2.6 td_user_unset
当您要清空用户的用户属性值时,您可以调用td_user_unset来对指定属性进行清空操作,如果该属性还未在集群中被创建,则td_user_unset不会创建该属性
TD_ASSERT(TD_OK == td_user_unset("account_id", "distinct_id", "test", ta));
td_user_unset: 的传入值为被清空属性的 Key 值。
2.7 td_user_delete
如果您要删除某个用户,可以调用td_user_delete将这名用户删除,您将无法再查询该名用户的用户属性,但该用户产生的事件仍然可以被查询到,该操作可能产生不可逆的后果,请慎用
TD_ASSERT(TD_OK == td_user_delete("account_id", "distinct_id", ta));
三、其他功能
3.1 BatchConsumer
当数据量过大或者网络异常时,有数据丢失的风险,不建议在正式环境中使用
批量实时地向 AE 服务器传输数据,不需要搭配传输工具,可设置缓存区大小,默认20,即缓存区保留的数据总数最大为20(20为每次上传的batch值,可设置)。
// 首先:修改 CMakeLists.txt 文件,打包 TDBatchConsumer 类型的库文件
struct TDAnalytics* ta = NULL;
struct TDConsumer* consumer = NULL;
//生成config
TDConfig *config = td_init_config();
// 配置appid和url
char* appid = "APPID";
char* serverURL = "SERVER_URL";
TD_ASSERT(TD_OK == td_add_string("push_url", serverURL, strlen(serverURL), config));
TD_ASSERT(TD_OK == td_add_string("appid", appid, strlen(appid), config));
// 生成SDK实例
if (TD_OK != td_init_consumer(&consumer, config)) {
fprintf(stderr, "Failed to initialize the consumer.");
return 1;
}
td_free_properties(config);
if (TD_OK != td_init(consumer, &ta)) {
fprintf(stderr, "Failed to initialize the SDK.");
return 1;
}
参数说明:
-
APPID: 您的项目的 APPID,可通过在 AE 后台项目管理页面获取 -
SERVER_URL: 数据上传的 URL- 如果您对接的是云服务,填入: https://global-receiver-ta.thinkingdata.cn
- 如果您使用私有化部署版本,请为数据采集地址绑定域名,并配置 HTTPS 证书:https://数据采集地址绑定域名

