menu
Is this helpful?

# 数据规则

本章节将会详细介绍 TE 后台的数据结构、数据类型以及数据限制。通过本章节,您将了解如何构建符合规则的数据,排查数据传输问题。

如果您使用的是 LogBus 或 RESTful API 上传数据,需要按照本章节中的数据规则对数据进行格式处理。

# 一、数据结构

TE 后台接受的是符合规则的 JSON 数据:如果使用的是 SDK 接入,则数据将会被转化成 JSON 数据进行传输。如果使用 LogBus 或 POST 方法上传数据,则数据需要是符合规则的 JSON 数据。

JSON 数据以行为单位:即一行一条 JSON 数据,对应物理意义上的一条数据,数据意义上对应的是用户产生一次行为,或者是设置一次用户属性。

数据格式及要求如下(为了方便阅读,数据经过排版,真实环境下请勿换行):

  • 以下是事件数据的样例:
{
  "#account_id": "ABCDEFG-123-abc",
  "#distinct_id": "F53A58ED-E5DA-4F18-B082-7E1228746E88",
  "#type": "track",
  "#ip": "192.168.171.111",
  "#uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "#time": "2017-12-18 14:37:28.527",
  "#event_name": "test",
  "properties": {
    "argString": "abc",
    "argNum": 123,
    "argBool": true
  }
}
  • 以下是用户属性设置的样例:
{
  "#account_id": "ABCDEFG-123-abc",
  "#distinct_id": "F53A58ED-E5DA-4F18-B082-7E1228746E88",
  "#type": "user_set",
  "#uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "#time": "2017-12-18 14:37:28.527",
  "properties": {
    "userArgString": "abc",
    "userArgNum": 123,
    "userArgBool": true
  }
}

"#type"的值可以替换为"user_setOnce"、"user_add"、"user_unset"、"user_append"、"user_del"

从结构和功能上,可以将一条 JSON 数据分为两个部分:

properties 的同层其他字段,组成了该条数据的基本信息,其中只包括以下几项:

  • 表示触发用户的账号 ID#account_id与访客 ID#distinct_id
  • 表示触发时间#time,可精确到秒或毫秒
  • 表示数据类型(事件还是用户属性设置)的#type
  • 表示事件名称的#event_name(仅事件数据带有)
  • 表示用户 IP 的#ip
  • 表示数据唯一性的#uuid

请注意,除以上几项外,其余以“#”开头的属性都需要放在 properties 的内层

properties 的内层,是该条数据的内容,也就是事件中的属性,或者需要设置的用户属性,在后台分析时作为属性或分析对象被直接使用。

从结构上来看,这两部分与报文头(Header)和报文体(Content)有些类似,接下来将会详细介绍这两部分各字段的含义。

# 1.1 数据信息部分

如下图红框标识,与"properties"同层的数个字段组成了该条数据的信息部分:

这些字段包含了这条数据的触发用户、触发时间等数据信息,其特点是所有字段都以“#”开头,本节将会梳理各字段的意义以及如何配置。


# 1.1.1 用户信息(#account_id#distinct_id

#account_id#distinct_id是 TE 后台用来识别用户的两个字段,其中#account_id为用户在登录状态下的 ID,#distinct_id为用户在未登录状态下标识,TE 后台会根据这个两个字段判断该行为的触发用户,其中优先根据#account_id进行判断,具体规则参见用户识别规则一章。

#account_id#distinct_id至少要传入一个,如果所有事件都是在用户登录状态下触发的,则只传入#account_id是可行的,如果有事件是在未登录状态(包括注册前)触发的,则建议将两个字段都填入。


# 1.1.2 数据类型信息(#type#event_name

#type决定了该条数据的类型,是用户的行为记录、还是修改用户属性的操作处理,每一条数据都需要配置#type字段#type的取值分为两类,track代表这条数据是用户行为记录,以user_开头代表对用户属性进行操作,具体意义如下:

  1. track:向事件表传入一个事件,事件的上传都为 track
  2. user_set:对用户表进行操作,覆盖一个或多个用户属性,如果该属性已有值存在,覆盖先前值
  3. user_setOnce:对用户表进行操作,初始化一个或多个用户属性,如果该属性已有值存在,则忽略本次操作
  4. user_add:对用户表进行操作,为一个或多个数值型用户属性做累加计算
  5. user_unset:对用户表进行操作,清空该名用户的一个或多个用户属性的属性值
  6. user_del:对用户表进行操作,删除该名用户
  7. user_append:对用户表进行操作,为用户的列表类型属性值添加元素
  8. user_uniq_append: 对用户表进行操作,为用户的列表类型属性值添加元素,并会进行一次全列表去重(去重保证前后原有的元素顺序不变)

#type的取值为track时,即该条数据是行为记录时,必须配置事件的名称#event_name,必须以字母开头,只能包含:字母(区分大小写)、数字和下划线“_”,长度最大为 50 个字符。请注意配置时不要带有空格。如果该条数据是修改用户属性的操作,则不需要#event_name字段。

需要注意的是,用户属性是用户具有节点意义的属性,不建议在短时间内进行频繁修改,对于需要频繁变更的属性,建议放在事件中作为事件属性


# 1.1.3 触发时间(#time

#time为事件产生的时间,必须要配置,格式必须是精确到毫秒("yyyy-MM-dd HH:mm:ss.SSS")或秒("yyyy-MM-dd HH:mm:ss")的字符串

尽管对 User 表的操作数据也需要配置#time,但对于用户属性的操作会按照后台收到数据的先后顺序进行操作。

比如用户重传了过去某天的 User 表操作数据,则无论是属性的覆盖还是初始化都会照常进行,并不会根据#time 字段进行判断


# 1.1.4 触发地点(#ip

#ip是设备的 IP 地址,可选配置,TE 将会根据 IP 地址计算用户的地理位置信息,如果您在"properties"中传入了#country、#province、#city 等地理位置属性,则会以您传入的值为准


# 1.1.5 数据唯一 ID(#uuid

#uuid是用以表示数据唯一性的字段,可选配置,格式必须为 uuid 的标准格式。TE 将会根据数据量,将会在一段时间内,在接收端校验是否短时间内出现相同#uuid的数据(即重复数据),并将重复数据直接抛弃,不再入库

需注意,通过#uuid进行的接收端校验只会对近几个小时接收到的数据进行校验,主要解决因网络抖动问题造成的短时数据重复,无法将接收到的数据与全量数据进行校验。如需对数据进行去重,请联系 TE 工作人员。


# 1.2 数据主体部分

数据的另一部分,则是properties内层所包含的数据,properties是一个 JSON 对象,里面的数据以键值对的形式表示。如果是用户行为数据,其代表了该行为的属性及指标(相当于行为表中的字段),这些属性及指标可在分析时直接使用;如果是用户属性的操作处理,则代表需要设置的属性内容。

key 值为该属性的名称,类型是字符串,自定义的属性必须以字母开头,只能包含:字母(忽略大小写)、数字和下划线“_”,且长度最大只能 50 个字符;另外还存在以#开头的 TE 预置属性,您可以在预置属性一章中了解更多信息,但需要注意,大多数情况下建议只使用自定义的属性,不使用#。

value 值为该属性的值,可以是数值、文本、时间、布尔、列表、对象、对象组,数据类型的表示方式如下表所示:

TE 数据类型 取值样例 取值说明 数据类型
数值 123,1.23 数据范围是-9E15 至 9E15 Number
文本 "ABC","上海" 字符的默认上限是 2KB String
时间 "2019-01-01 00:00:00","2019-01-01 00:00:00.000" "yyyy-MM-dd HH:mm:ss.SSS"或"yyyy-MM-dd HH:mm:ss",如需表示日期,可使用"yyyy-MM-dd 00:00:00" String
布尔 true,false - Boolean
列表 ["a","1","true"] 列表中的元素都会转变为字符串类型,列表内最多500个元素 Array(String)
对象 {"hero_name":"刘备","hero_level":22,"hero_equipment": ["雌雄双股剑","的卢"],"hero_if_support":false} 对象内的每个子属性(Key)都有自己的数据类型,取值说明请参考上面对应类型的普通属性 对象内最多100个子属性 Object
对象组 [{"hero_name":"刘备","hero_level":22,"hero_equipment": ["雌雄双股剑","的卢"],"hero_if_support":false}, {"hero_name":"刘备","hero_level":22,"hero_equipment": ["雌雄双股剑","的卢"],"hero_if_support":false}] 对象组内的每个子属性(Key)都有自己的数据类型,取值说明请参考上面对应类型的普通属性 对象组内最多500个对象 Array(Object)

需要注意,所有属性的类型会根据第一次收到该属性值的类型所决定,后续数据的类型必须与相应属性的类型一致,类型不匹配的属性将被丢弃(该条数据其余符合类型的属性将保留),TE 不会进行类型的兼容转换。

# 二、数据处理规则

TE 服务器在收到数据之后,会进行一些处理,本节将会结合实际使用场景,TE 后台的处理规则:

# 2.1 收到新事件数据

在收到新增事件的数据后,TE 后台会自动地创建新增事件与其属性的关联模型;如果收到了新的属性,则首次收到该属性时的属性类型将会设置为该属性的类型,属性的类型之后将不能修改。


# 2.2 增添事件的属性

如果需要对已有事件增添属性,只需要在上传数据时将新增属性一并传入即可,TE 后台将会动态地关联事件与新增属性,不需要进行其他配置。


# 2.3 属性不一致的处理

当收到一条事件数据,其中某属性的类型与后台已存的该属性的类型不一致,则该属性的值将会被抛弃(即取值为 null)。


# 2.4 弃用事件属性

如果需要弃用事件某个属性,则只需要在 TE 后台的数据管理模块中将该属性隐藏即可,后续传输的数据可不传该属性。TE 后台不会删除该属性的数据,隐藏操作也是可逆的,如果在属性被隐藏后仍传输该属性,该属性的值仍会被保留。


# 2.5 多事件共有属性

不同事件的同名属性被视为是同一属性,类型一致,因此需要保证所有同名属性的类型一致,以避免由于类型不一致而导致的属性值被抛弃。


# 2.6 用户表操作逻辑

修改用户在用户表中的数据,也就是上报数据中#type字段为user_setuser_setOnceuser_adduser_unsetuser_appenduser_del的数据,本质上可以看作是一条指令,也就是对该条数据所指用户的用户表数据进行操作,操作的类型由#type字段决定,而操作的内容以properties中的属性所决定。

以下是主要的用户表属性操作的具体逻辑:

# 2.6.1 覆盖用户属性(user_set)

根据数据中的用户 ID 确定进行操作的用户,再根据properties中的属性,覆盖所有属性,如果某个属性不存在则新建该属性。

# 2.6.2 初始化用户属性(user_setOnce)

根据数据中的用户 ID 确定进行操作的用户,再根据properties中的属性,对未赋值(为空)的属性进行设置,如果该用户的某需要设置的属性已经有值,则不会进行覆盖,如果某个属性不存在则新建该属性。

# 2.6.3 累加用户属性(user_add)

根据数据中的用户 ID 确定进行操作的用户,再根据properties中的属性,对数值型的属性进行累加操作,如果传入负值相当于原属性值减去传入值,如果该用户的某需要设置的属性未赋值(为空),则会默认设置为 0 后再进行累加操作,如果该属性不存在则新建该属性。

# 2.6.4 清空用户属性值(user_unset)

根据数据中的用户 ID 确定进行操作的用户,再根据properties中的属性,清空其中的所有属性(即设置成 NULL),如果某个属性不存在不会新建该属性。

# 2.6.5 添加列表型用户属性的元素(user_append)

根据数据中的用户 ID 确定进行操作的用户,再根据properties中的属性,对列表型的属性进行添加元素操作

# 2.6.6 删除用户(user_del)

根据数据中的用户 ID 确定进行操作的用户,将该用户从用户表中删除,该用户的事件数据不会被删除。

# 2.6.7 添加列表去重型用户属性的元素(user_uniq_append)

根据数据中的用户 ID 确定进行操作的用户,再根据properties中的属性,对列表型的属性进行添加元素操作,并进行一次全列表去重(去重保证前后原有的元素顺序不变)


# 三、数据限制

  • 事件类型及属性数量限制

出于性能考虑,TE 后台会默认地对项目的事件类型及属性的数量进行限制:

限制 事件种类上限 事件属性上限 用户属性上限
建议不超过 100 300 100
硬件上限 500 1000 500

管理员可以进入“项目管理”页面,可查询各项目已经使用的事件类型以及属性数,联系 TE 工作人员可申请上调事件种类、属性属性的上限。

  • 账号 ID(#account_id)、访客 ID(#distinct_id)长度限制
  * 3.1版本之前创建的项目:64个字符;如需扩大至128个字符,请联系TE工作人员

  * 3.1版本及之后创建的项目:128个字符
  • 事件、属性名称限制
  * 事件名:`String`类型,以字母开头,可包含数字,大小写字母和下划线“\_”,长度最大为50个字符

  * 属性名:`String`类型,以字母开头,可包含数字,字母(忽略大小写)和下划线“\_”,长度最大为50个字符。只有预置属性能以#号开头。
  • 文本、数值、列表、对象、对象组类型属性数据范围
  * 文本:字符串上限是2KB

  * 数值:数据范围是-9E15至9E15

  * 列表:最多包含500个元素;每个元素为字符串类型,且上限为255字节
  
  * 对象:最多包含100个子属性;
  
  * 对象组:最多包含500个对象;
  • 数据接收时限
  * 服务端数据接收事件上限:相对服务器时间的前三年至后3天

  * 客户端数据接收事件上限:相对服务器时间的前10天至后3天

# 四、其他规则

  1. 请以 UTF-8 对数据进行编码,以避免乱码问题
  2. TE 后台的属性名不区分大小写,建议使用"_"作为分词分隔符
  3. TE 后台默认只接收最近三年的数据,超过三年的数据将无法录入,如需录入三年之前的数据,可联系 TE 工作人员放宽时限

# 五、常见问题

本节总结了由于数据不符合数据规则而引起的常见问题,如果出现了数据传输问题,可以先根据本节内容进行排查

# 5.1 TE 后台没有收到数据

如果使用的是 SDK 传输:

  1. 请确认 SDK 是否被成功集成
  2. 排查 APPID 与传输的 URL 是否设置正确,传输端口号及传输方式对应后缀有无遗漏

如果使用的是 LogBus 或 POST 方法传输:

  1. 请确认 APPID 与传输的 URL 是否设置正确,传输端口号及传输方式对应后缀有无遗漏
  2. 请检查数据是否以 JSON 格式传输,并确保一行一条 JSON 数据
  3. 请检查数据信息部分的 key 值是否以"#"开头,是否遗漏了必要字段
  4. 请检查数据信息部分的 value 值的类型与格式(时间格式)是否正确
  5. 请检查"#event_name"的 value 值是否符合规范,不包含汉字,空格等字符
  6. "properties"请不要以"#"开头
  • 另外,请注意用户属性设置并不会产生行为记录,因此如果只上传了user_set等数据,在后台的行为分析模型(除 SQL 查询外)中无法直接查询到数据
  • 请注意上传数据的时间,过早时间(超过三年)的数据将不会录入;如果上传数据为历史数据,则可能是查询时段没有涵盖上传数据的时间,请调整查询时段

# 5.2 数据有缺失,某些属性没有收到

  1. 请确认数据主体部分的属性 key 值符合规范,不包含汉字,空格等字符
  2. 请确认数据主体部分的属性中,以"#"开头 key 值属于预置属性
  3. 请检查缺失属性在上传时的类型是否与后台该属性的类型一致,可在后台的元数据管理中查看已收到属性的类型

# 5.3 数据传输有误,希望删除数据

  1. 私有化服务的用户,可使用数据删除工具自助式的删除数据;如果是云服务的用户,可联系 TE 工作人员进行数据删除
  2. 如果数据有较大改动,建议直接新建项目,建议用户在正式传输数据之前先在测试项目下进行完备的数据测试