# 数据格式

方舟支持多种 SDK 上报数据，接口会有所不同，但底层数据都使用统一的数据格式，尤其是通过工具导入数据时，也需要符合相应的数据格式。同时，不同的属性，会有不同的数据类型，在分析时对应不同的计算方式，所以在上报数据时需要注意采用合适的格式。

## 上报数据的格式

数据整体是 JSON 格式，描述一条事件或者属性。

**Event 数据样例**

```javascript
[
    {
        "appid":"demo",
        "xwho":"9692043c-7d85-417a-b84e-fd37e1b7a67e",
        "xwhat":"confirmOrder",
        "xwhen":1533110482778,
        "xcontext":{
            "$pagename":"com.analysys.demo.activity.MainActivity",
            "$channel":"豌豆荚",
            "$manufacturer":"Xiaomi",
            "$app_version":"4.0.4.001",
            "$model":"MIX 2S",
            "$os":"Android",
            "$os_version":"8.0.0",
            "$network":"WIFI",
            "$screen_width":1080,
            "$screen_height":2030,
            "$brand":"Xiaomi",
            "$is_first_day":true,
            "$lib":"Android",
            "$platform":"Android",
            "$is_login":false,
            "$lib_version":"4.0.4",
            "$debug":2，
            "order_price":1213.23
        }
    }
]
```

上述字段说明：

* `appid`：字符串类型，记录项目的 AppKey，创建项目后生成；
* `xwho`：字符串类型，记录用户 ID，调用接口生成；
* `xwhat`：字符串类型，记录事件 ID，必须是合法的变量名，由字母、数字和下划线组成，不能以数字开头，对于系统预置的事件以 $ 开头 ;
* `xwhen`：数据值类型，记录事件发生的时间戳，精确到毫秒；
* `xcontext`：事件的属性，以 dict 的形式存在，其中每个属性，有相应格式。以 $ 开头表示为系统预置的属性，其属性值数据类型都是约定好的，自定义的属性不要以 $ 开头，同一个属性 ID 在不同事件中的定义和数据类型应该保持一致。

**Profile 数据样例**

```javascript
[
{
    "appid":"demo",
    "xwho":"9692043c-7d85-417a-b84e-fd37e1b7a67e",
    "xwhat":"$profile_set",
    "xwhen":1533110558121,
    "xcontext":{
        "Email":"yonghu@163.com",
        "$mac":"9c:2e:a1:fe:b7:eb",
        "$lib":"Android",
        "$platform":"Android",
        "$is_login":false,
        "$lib_version":"4.0.4",
        "$debug":2
    }
}
]
```

Profile 信息是通过一些特殊的事件上报，数据格式要求和事件相同。Profile 系列事件包括：

* $profile\_set
* $profile\_set\_once
* $profile\_unset
* $profile\_increment
* $profile\_append
* $profile\_delete

> 特别说明：
>
> 建议您在上报数据时，用户属性ID 和 事件属性ID 使用小写英文字母和下划线组合命名，例如 pagename 、page\_name；
>
> 不建议使用含大写字母的属性ID，例如 pageName 、pageTitle。
>
> 因为易观方舟会将 事件属性ID 和 用户属性ID 中的大写字母强制转换为小写字母。

## 属性值的数据类型

除了整体数据要以 JSON 作为数据传输格式之外，属性值的数据类型也会对应一定格式。

方舟定义了以下数据类型：

| 数据类型 | JSON类型   | 说明                                                                             | 示例                        |
| ---- | -------- | ------------------------------------------------------------------------------ | ------------------------- |
| 字符串  | string   | 使用UTF-8编码后最大长度1024字节                                                           | "易观方舟"                    |
| 数值   | number   | -9E14到9E14, 小数点后最多保留3位                                                         | 123 或者123.12              |
| 布尔   | boolean  | true/false                                                                     | true/false                |
| 日期   | datetime | 格式：yyyy-MM-dd HH:mm:ss.SSS 或yyyy-MM-dd HH:mm:ss 或yyyy-mm-dd                    | "2018-06-18 18:18:18.188" |
| 集合   | array    | 元素为字符串，去重后最大元素个数 100，其中每个元素使用 UTF-8 编码后最大长度 255字节；是去重的无序的字符串集合，输入可有重复，导入过程中会去重 | \[ "写作","摄影","烹饪" ]       |

方舟预置的一些事件属性和用户属性，也会同时定义好数据类型，详见[《预置事件和属性》](/integration/prepare/default-data.md)。

{% hint style="danger" %}
**方舟不会自动对数据类型错误的属性进行转换**

假如我们有一个表示商品数量的属性 product\_number 首次上报时是数值（number）类型，那么数据库就会将存储这个属性的字段的类型设置为数值（number）。如果接下来 product\_number 收到非数值类型的值时，这一整条日志都会被标记为异常，进入错误队列，而不会进入方舟参与到正常计算中。

错误队列中的数据会保留7天，如果需要恢复当中的数据，请随时联系我们。
{% endhint %}

{% hint style="info" %}
如果发现数据异常变少，可以通过“**数据入库检查**”中的“**错误数据日志**”查看日志是否因为此种情况而被抛弃。
{% endhint %}

{% content-ref url="/pages/-LazhUvrTssSWEg1T2b8" %}
[数据入库验证](/integration/data-verification/data_debug.md)
{% endcontent-ref %}

**不同数据类型属性值的应用**

数据上报中的属性，在分析时可以作为条件查询，也可以作为维度去细分，之所以需要定义不同属性值的数据类型，就是为了进行合适的运算和维度细分，例如 “支付订单金额” ，分析时希望对它进行求和、最大值、最小值、均值等运算，这就要求这个属性值的类型应该是数值型。

以下说明不同数据类型作为细分维度和过滤条件时的使用差异：

### 维度

| 数据类型 | 维度处理方式                                        | 举例属性                                                                                            | 查询用户数，按举例维度细分                                                                                                       |
| ---- | --------------------------------------------- | ----------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| 字符串  | 按离散值                                          | <p>商品类别<br>上报的属性值：<br>3C电器、服装、化妆品……</p>                                                         | <p>3C电器：12人<br>服装：12人<br>化妆品：18人</p>                                                                                |
| 数值型  | <p>按离散值<br>自定义区间分组</p>                        | <p>商品价格<br>上报的属性：<br>12、20、90、300……</p>                                                         | <p>按离散值：<br>12：2人<br>20：3人<br>90：13人<br>300：1人<br>按用户自定义区间的话可能是：<br>(-∞,50)：5人<br>\[50,200)：13人<br>\[200,+∞]：1人</p> |
| 布尔值  | 按离散值                                          | <p>是否使用优惠券<br>上报的属性值：<br>true、false</p>                                                         | <p>使用了优惠券的：12人<br>没有使用优惠券的：18人</p>                                                                                  |
| 日期时间 | <p>按分钟、小时、日、周、月、季、年<br>按时段汇总：按分钟、小时、日、周，月</p> | <p>下单时间<br>上报的属性值：<br>2017-03-12 12:12:32、<br>2018-03-15 12:12:32、<br>2018-04-12 12:12:32……</p> | <p>不按时段汇总，按月：<br>2017年3月：23人<br>2018年3月：27人<br>2018年4月：12人<br>按时段汇总，按月：<br>每年3月：50人<br>每年4月：12人</p>                 |
| 集合   | 按集合字符串                                        | <p>用户爱好<br>上报的属性值：<br>\[网球，摄影]、\[户外，摄影]、\[户外、壁球]……</p>                                          | <p>\[网球，摄影]：34人<br>\[户外，摄影]：53人<br>\[户外、壁球]：23人</p>                                                                 |

### 条件

**字符串类型**

| 操作符          | 使用场景                                         | e.g.                            |
| ------------ | -------------------------------------------- | ------------------------------- |
| =(等于)        | 当输入一个值时，表示等于某个具体确定的属性值；当输入多个时，表示满足其中的一项或多项   | 设备品牌 = 苹果，小米；设备品牌满足苹果、小米中的任意一个  |
| ≠（不等于）       | 完全排除输入的某个或多个属性值                              | 设备品牌 ≠ 苹果，小米；设备品牌不满足苹果、小米中的任何一个 |
| like（包含）     | 查找属性值中包含某些字符的值                               | 设备品牌中包含苹果这个词的                   |
| notlike（不包含） | 排除属性值中包含某些字符的值                               | 设备品牌中不包含苹果这个词的                  |
| 有值           | 查找有属性值的数据                                    | 有设备品牌名称的                        |
| 无值           | 查找无属性值的数据                                    | 无设备品牌名称的                        |
| 正则匹配         | 用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等  | -                               |
| 正则不匹配        | 用来检查一个串是否不含有某种子串、将匹配的子串替换或者从某个串中排除符合某个条件的子串等 | -                               |

**数值型**

| 操作符     | 使用场景        | e.g.             |
| ------- | ----------- | ---------------- |
| = (等于)  | 等于某个具体数字    | 商品金额 = 100       |
| ≠（不等于）  | 不等于某个数字     | 商品金额 ≠ 100       |
| <（小于）   | 小于某个数字      | 商品金额 < 100       |
| ≤（小于等于） | 小于等于某个数字    | 商品金额 ≤ 100       |
| >（大于）   | 大于某个数字      | 商品金额 ＞ 100       |
| ≥（大于等于） | 大于等于某个数字    | 商品金额 ≥ 100       |
| 介于区间    | 在某个数据区间内的数值 | 100＜商品金额 ≤   500 |
| 有值      | 查找有属性值的数据   | 有商品金额的           |
| 无值      | 查找无属性值的数据   | 无商品金额的           |

**布尔值**

| 操作符 | 使用场景      | e.g.     |
| --- | --------- | -------- |
| 为真  | 某个判断为真    | 是否成功 = 是 |
| 为假  | 某个判断为假    | 是否成功 = 否 |
| 有值  | 查找有属性值的数据 | 有值       |
| 无值  | 查找无属性值的数据 | 无值       |

**日期时间**

| 操作符      | 使用场景          | e.g.                       |
| -------- | ------------- | -------------------------- |
| 绝对时间     | 在某个具体的时间范围    | 在 2018/12/14-   2018/12/17 |
| 相对当前时间点  | 在相对当前的某段时间里   | 在近 30 天内                   |
| 相对事件发生时间 | 在相对事件发生的某段时间里 | 登录之前的 5 分钟里                |
| 有值       | 查找有属性值的数据     | 有日期                        |
| 无值       | 查找无属性值的数据     | 无日期                        |

**字符串集合**

| 操作符          | 使用场景         | e.g.        |
| ------------ | ------------ | ----------- |
| like（包含）     | 集合中包含某个字符的值  | 用户标签中包含 摄影  |
| notlike（不包含） | 集合中不包含某个字符的值 | 用户标签不包含设计摄影 |
| 有值           | 查找有属性值的数据    | 有用户标签       |
| 无值           | 查找无属性值的数据    | 无用户标签       |

{% hint style="info" %}
以上内容没有解答我的问题？[点击我进入方舟论坛去反馈](https://www.analysysdata.com/forum/index) 🚀
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://arkdocs.analysys.cn/integration/prepare/data-type.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
