# 数据规则

> 来源：https://help.gravity-engine.com/docs/getting-started/data-rules
> 说明事件名、属性名、数据类型和取值限制等上报规则，供客户端 SDK 与服务端 API 接入前核对。



本章节将会详细介绍 引力引擎 后台的数据结构、数据类型以及数据限制。通过本章节，您将了解如何构建符合规则的数据。

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

## 1. 数据结构 [#1-数据结构]

引力引擎 后台接受的是符合规则的 `JSON` 数据：如果使用的是 SDK 接入，则数据将会被转化成 `JSON` 数据进行传输。如果使用 API POST 方法上传数据，则数据需要是符合规则的 `JSON` 数据。

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

数据格式及要求如下（为了方便阅读，数据经过排版，真实环境下请勿换行）：

* 以下是行为事件数据的样例：

```json
// 广告观看事件
{
  "type": "track",
  "event": "$AdShow",
  "time": 1675927637000,
  "time_free": false,
  "properties": {
    "$ad_type": "reward",
    "$ecpm": 500,
    "$adn_type": "gdt"
  }
}

```

* 以下是用户属性设置的样例：

```json
// 设置用户属性
{
  "type": "profile",
  "event": "profile_set",
  "time": 1675927637000,
  "time_free": false,
  "properties": {
    "$age": 23,
    "$gender": "女"
  }
}

```

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

### 1.1 数据信息部分 [#11-数据信息部分]

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

* 表示事件类型的 `type` 字段，该字段决定了该条数据的类型，是用户的行为记录、还是修改用户属性的操作处理，枚举可选值为如下：
  * `track` 表明为行为事件
  * `profile` 表明为用户属性设置事件
* 表示事件名称的 `event` 字段
  * 在行为事件数据下，`event` 字段为当前事件对应的英文名称，可以在 [元事件](https://web.gravity-engine.com/#/manage/metadata/metaEvent) 页面进行配置。
  * 用户属性设置事件下， `event` 字段枚举可选值如下：
    * `profile_set` ：对用户表进行操作，覆盖一个或多个用户属性，如果该属性已有值存在，覆盖先前值
    * `profile_set_once` ：对用户表进行操作，初始化一个或多个用户属性，如果该属性已有值存在，则忽略本次操作
    * `profile_increment` ：对用户表进行操作，为一个或多个数值型用户属性做累加计算
    * `profile_number_max` ：对用户表进行操作，为一个或多个数值型用户属性做取最大值计算
    * `profile_number_min` ：对用户表进行操作，为一个或多个数值型用户属性做取最小值计算
    * `profile_append` ：对用户表进行操作，为用户的列表类型属性值添加元素
    * `profile_uniq_append` ：对用户表进行操作，为用户的列表类型属性值添加元素，并会进行一次全列表去重（去重保证前后原有的元素顺序不变）
    * `profile_unset` ：对用户表进行操作，清空该名用户的一个或多个用户属性的属性值
    * `profile_delete`：对用户表进行操作，删除该名用户的所有用户属性
* 表明事件产生时间的 `time` 字段，格式必须是精确到毫秒的时间戳
* 表明是否忽略时间正确性校验的 `time_free` 字段，默认 false，建议在导入历史数据时使用，SDK 采集的实时数据不建议使用。

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

### 1.2 数据主体部分 [#12-数据主体部分]

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

```json
{
  "type": "track",
  "event": "$AdShow",
  "time": 1675927637000,
  "time_free": false,
  "properties": {
    "$ad_type": "reward",
    "$ecpm": 500,
    "$adn_type": "gdt"
  }
}
```

key 值为该属性的名称，类型是字符串，自定义的属性必须以字母开头，只能包含：字母（忽略大小写）、数字和下划线“\_”，且长度最大只能 50 个字符；另外还存在以 `$` 开头的属性，此类属性为预置属性，预置属性不需要特别设置，SDK 会在特定的事件发生时默认采集。

value 值为该属性的值，可以是字符串、整型、浮点、布尔、日期以及时间类型，数据类型的表示方式如下表所示：

| 引力数据类型 | 取值样例                                               | 取值说明                      | 数据类型     |
| ------ | -------------------------------------------------- | ------------------------- | -------- |
| 文本     | "ABC"                                              | 字符长度上限是 8192              | String   |
| 整数     | 123                                                | 数据范围是-9E15 至 9E15         | Integer  |
| 浮点数    | 1.2                                                | 数据范围是-9E15 至 9E15         | Float    |
| 布尔值    | true,false                                         | -                         | Bool     |
| 时间     | "2023-01-01 00:00:00"                              | 上报格式 yyyy-MM-dd HH:mm:ss  | DateTime |
| 日期     | "2023-01-01"                                       | 上报格式 yyyy-mm-dd           | Date     |
| 列表     | \["Interstellar", "The Negro Motorist Green Book"] | 默认为字符串元素的数组，数组最大元素个数为 500 | Array    |

> **属性值的类型为在引力引擎后台创建该属性值时确定的类型，如果数据中某个属性的值的类型与此前确定的类型不符，此次事件将被系统丢弃!**

## 2. 用户表操作逻辑 [#2-用户表操作逻辑]

修改用户在用户表中的数据，也就是上报数据中 `event` 字段为`profile_set` 、 `profile_set_once` 、 `profile_increment` 、`profile_number_max` 、`profile_number_min` 、 `profile_append` 、 `profile_uniq_append` 、 `profile_unset` 、 `profile_delete` 的数据，本质上可以看作是一条指令，也就是对该条数据所指用户的用户表数据进行操作，操作的类型由 `event`字段决定，而操作的内容以 `properties` 中的属性所决定。

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

| **字段**                | **描述**         | **备注**                                                                                         |
| --------------------- | -------------- | ---------------------------------------------------------------------------------------------- |
| profile\_set          | 覆盖用户属性         | 根据 `properties`中的属性，覆盖所有属性。                                                                    |
| profile\_set\_once    | 初始化用户属性        | 根据 `properties`中的属性，对未赋值（为空）的属性进行设置，如果该用户的某需要设置的属性已经有值，则不会进行覆盖。                                |
| profile\_increment    | 累加用户属性         | 根据 `properties`中的属性，对数值型的属性进行累加操作，如果传入负值相当于原属性值减去传入值，如果该用户的某需要设置的属性未赋值（为空），则会默认设置为 0 后再进行累加操作。 |
| profile\_number\_max  | 用户属性取最大值       | 根据 `properties`中的属性，对数值型的属性进行取最大值操作，如果该用户的某需要设置的属性未赋值（为空）。                                     |
| profile\_number\_min  | 用户属性取最小值       | 根据 `properties`中的属性，对数值型的属性进行取最小值操作，如果该用户的某需要设置的属性未赋值（为空）。                                     |
| profile\_append       | 添加列表型用户属性的元素   | 根据 `properties`中的属性，对列表型的属性进行添加元素操作                                                            |
| profile\_uniq\_append | 去重添加列表型用户属性的元素 | 根据 `properties`中的属性，对列表型的属性进行去重添加元素操作                                                          |
| profile\_unset        | 清空用户属性值        | 根据 `properties`中的属性，清空其中的所有属性（字符串型设置为空字符串，数值型设置为 0，布尔型设置为 false），如果某个属性不存在不会新建该属性。             |
| profile\_delete       | 删除用户           | 将该用户的所有用户属性从用户表中删除，该用户的事件数据不会被删除。                                                              |
