数据格式
|
收藏
神策分析支持多种不同语言的 SDK,这些 SDK 虽然在外部提供的接口上有所不同,但是在内部实现上都使用统一的数据格式,并且都支持直接导入以文件形式存储的符合要求格式的数据,在这里,我们对数据格式进行一个更加细致的描述。
- 注意:这里描述的是底层数据传输格式的定义,和具体 SDK 的调用接口无关
- 注意:$is_login_id 参数说明
数据整体格式
日志文件是一行一个 JSON,物理上对应一条数据,逻辑上对应一个描述了用户行为的事件,或是描述一个或多个用户属性的 Profile 操作。
track:
记录一个 Event 及关联的 Properties。
数据样例:
{
"distinct_id": "123456",
"time": 1434556935000,
"type": "track",
"event": "ViewProduct",
"project": "ebiz_test",
"time_free": true, //建议在导入历史数据时使用,SDK 采集的实时数据不建议使用
"identities":{
"$identity_android_id":"0f485d4daaadedae5f"
},
"properties": {
"$is_login_id":true, //此参数请慎重使用,详细介绍请参考文档底部 8.1 $is_login_id 参数说明
"$app_version":"1.3",
"$wifi":true,
"$ip":"180.79.35.65",
"$province":"湖南",
"$city":"长沙",
"$user_agent":"Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_2 like Mac OS X) AppleWebKit/602.1.50 (KHTML, like Gecko) CriOS/58.0.3029.113 Mobile/14F89 Safari/602.1",
"$screen_width":320,
"$screen_height":568,
"product_id":12345,
"product_name":"苹果",
"product_classify":"水果",
"product_price":14.0
}
}
对于上述字段的说明如下:
- distinct_id:类型是字符串,对用户的标识,对未登录用户,可以填充设备标识、CookieID 等,对于登录用户,则应该填充注册账号;这里的例子,我们假设是一个登录用户,所以填充的是一个登陆 ID;
- time:类型是数值,事件发生的实际时间戳,精确到毫秒;
- type:track 表明是记录一个 Event ,这里我们假设是一个商品浏览行为;
- event:事件名,需是合法的变量名,即不能以数字开头,且只包含:大小写字母、数字、下划线和 $,其中以 $ 开头的表明是系统的预置事件,自定义事件名请不要以 $ 开头,且 event 字段长度最大为 100;
- project:这条数据所属项目名,若不指定该参数,则需要使用该字段时取值 default,即默认项目。指定的项目必须是系统中已经存在的项目,否则这条数据将无效,更多项目相关请参见多项目;
- time_free:可选字段,表示不根据事件发生时间过滤该事件。只要出现 time_free 这个 key 且 value 不为 null,将不再校验 time 是否在允许导入的时间范围内。导入历史数据时可能会用到该字段;
- identities:全域用户关联业务中用户标识字段,可包含多个用户标识;
properties:这个 Event 的具体属性,以 dict 的形式存在。其中以 $ 开头的表明是系统的预置属性,它的类型和中文名已经预先定义好了。自定义属性名需要是合法的变量名,不能以数字开头,且只包含:大小写字母、数字、下划线,自定义属性不能以 $ 开头;同一个名称的 property,在不同 event 中,必须保持一致的定义和类型;同一个名称的 property 大小写不可以相同,如果已经存在小写属性就不可再导入对应大写属性(比如元数据中有 abc 属性名,不能再传 ABC,Abc 等属性名),否则数据会校验失败不入库。
- $is_login_id:判断 distinct_id 对应的是否是一个注册账号;
- $app_version:用户所使用的 App 的版本;
- $wifi:这条事件发生时,用户是否在使用 wifi;
- $ip:用户使用设备的 IP。若数据中出现 $ip,且数据中没有 $province 或 $city 字段,将使用该 IP 解析出省市信息填入缺失字段;
- $province、$city:省、市,在没有填充这两个字段的时候,会根据 IP 进行解析;
- $user_agent:可选参数。如果传入该参数,则解析 User-Agent,解析结果包括:设备制造商、设备型号、操作系统、操作系统版本、浏览器、浏览器版本、爬虫名称(如果是爬虫);目前是神策是通过 UA 判断并有一个默认的属性 $bot_name (爬虫名称),但是有两种情况无法判断,第一种:如果 UA 里没有标明、且会触发 JS 脚本的非法爬虫。第二种:如果爬虫没有触发 JS 脚本,那么也不会触发我们的 SDK ,所以本身就不会被统计到。对于爬虫种类,不能提前把所有的种类都加进去,主流的神策都加了,其它的属于不太常见的,量较少。
- $screen_width、$screen_height:屏幕的宽和高;
- product_id、product_name、product_classify、product_price:跟商品相关的一些具体属性。
track_signup:
这个接口是一个较为复杂的功能,请在使用前先阅读 2021-10-19_10-11-05_.标识用户 v1.13,并在必要时联系我们的技术支持人员。
数据样例:
{
"distinct_id":"130xxxx1234",
"original_id":"0f485d4d12345e5f",
"time": 1434557935000,
"type": "track_signup",
"event": "$SignUp",
"project": "ebiz_test",
"identities":{
"$identity_android_id":"0f485d4d12345e5f",
"$identity_login_id":"130xxxx1234"
},
"properties": {
"$manufacturer":"Apple",
"$model": "iPhone5,2",
"$os":"iOS",
"$os_version":"7.0",
"$app_version":"1.3",
"$wifi":true,
"$ip":"180.79.35.65",
"$province":"湖南",
"$city":"长沙",
"$screen_width":320,
"$screen_height":568
}
}
这条数据表示,一个匿名 ID 为 0f485d4d12345e5f 的用户,成功完成了注册,注册后的注册 ID 是 130xxxx1234。并且系统后台,会将 original_id 为 0f485d4d12345e5f 的用户和 distinct_id 为 130xxxx1234 的用户,当做同一个用户对待。需要注意的是,此接口中的 original_id 为必须字段,表示与注册 ID 进行关联的匿名 ID。
Profile 相关操作
Profile 相关操作,主要是用来设置用户的 Profile 的,提供了如下一系列接口:
profile_set:
直接设置一个用户的 Profile,如果用户或者 Profile 的字段已存在,则覆盖,不存在则自动创建。
数据样例:
{
"distinct_id": "12345",
"type": "profile_set",
"time": 1435290195610,
"project": "ebiz_test",
"identities":{
"$identity_android_id":"0f485d4da1111fe5f",
"$identity_login_id":"12345"
},
"properties": {
"$province":"湖南",
"FavoriteFruits": ["苹果","香蕉","芒果"],
"Age":33,
"$city":"长沙",
"IncomeLevel": "3000~5000",
"$name": "小明",
"Gender":"男",
"$signup_time": "2015-06-26 11:43:15.610"
}
}
profile_set_once
直接设置一个用户的 Profile。与 profile_set 接口不同的是,如果用户或者 Profile 的字段已存在,则这条记录会被忽略而不会覆盖已有数据,如果 Profile 不存在则会自动创建。因此,profile_set_once 比较适用于为用户设置首次激活时间、首次注册时间等只在首次设置时有效的属性。
数据样例:
{
"distinct_id": "12345",
"type": "profile_set_once",
"time": 1435290195610,
"project": "ebiz_test",
"identities":{
"$identity_android_id":"0f485d4da1111fe5f",
"$identity_login_id":"12345"
},
"properties": {
"$province":"湖南",
"FavoriteFruits": ["苹果","香蕉","芒果"],
"Age":33,
"$city":"长沙",
"IncomeLevel": "3000~5000",
"$name": "小明",
"Gender":"男",
"$signup_time": "2015-06-26 11:43:15.610"
}
}
profile_increment:
增加或减少一个用户的某个 NUMBER 类型的 Profile 值,比如给用户属性 Age 的值加 1 或者减 1 。如果用户表( users 表)中不存在这个用户,则会在用户表中自动创建该用户的 id 记录,并给该用户设置相应的 Profile 属性值,会在默认值 0 的基础上增加上传的 Profile 值。
数据样例:
{
"distinct_id": "12345",
"type": "profile_increment",
"time": 1435290200354,
"project": "ebiz_test",
"identities":{
"$identity_android_id":"0f485d4da1111fe5f",
"$identity_login_id":"12345"
},
"properties": {
"Age": 1
}
}
profile_delete:
删除一个用户的整个 Profile。
数据样例:
{
"distinct_id": "12345",
"type": "profile_delete",
"time": 1437290200354,
"project": "ebiz_test",
"identities":{
"$identity_android_id":"0f485d4da1111fe5f",
"$identity_login_id":"12345"
},
"properties":{
}
}
profile_append:
向某个用户的某个数组类型的 Profile 添加一个或者多个值。如果本次上传的值,与系统中已存在的值有重复,默认是不会去重的。如果本次上传的值,有重复项,也不会去重的。
数据样例:
{
"distinct_id": "12345",
"type": "profile_append",
"time": 1437280200354,
"project": "ebiz_test",
"identities":{
"$identity_android_id":"0f485d4da1111fe5f",
"$identity_login_id":"12345"
},
"properties": {
"FavoriteFruits": ["橘子","西瓜"]
}
}
profile_unset:
将某个用户的某些属性值设置为空。另外,为了与其它接口保持一致,在提交的数据上,属性的值请设置为非 null 的任何值,例如 true。
数据样例:
{
"distinct_id":"12345",
"type":"profile_unset",
"time":1437280200354,
"project": "ebiz_test",
"identities":{
"$identity_android_id":"0f485d4da1111fe5f",
"$identity_login_id":"12345"
},
"properties":{
"Age":true,
"FavoriteFruits":true
}
}
Item 相关操作
Item 相关操作,主要是用来设置 Item 的具体内容,提供了如下一系列接口:
item_set:
直接设置一个 Item,如果 Item 的字段已存在,则覆盖,不存在则自动创建。
数据样例:
{
"type":"item_set",
"item_id":"12",
"item_type":"dub",
"project": "ebiz_test",
"properties":{
"title":"because of u",
"sub_title":"st",
"xxx":"xxx"
}
}
对上述字段的解释如下:
- type:item_set 表明是设置一个 item;
- item_id:表示 item 的 id
- item_type:item 表的类型,区分不同的 item 表。需是合法的变量名,即不能以数字开头,且只包含:大小写字母、数字、下划线和 $,且 item_type 字段长度最大为 100;
- project:这条数据所属项目名,若不指定该参数,则需要使用该字段时取值 default,即默认项目。指定的项目必须是系统中已经存在的项目,否则这条数据将无效,更多项目相关请参见 多项目;
- properties:这个 item 的具体属性,以 dict 的形式存在。属性名需要是合法的变量名,不能以数字开头,且只包含:大小写字母、数字、下划线;
item_delete:
删除整个 Item 内容。
数据样例:
{
"type":"item_delete",
"item_id":"16",
"item_type":"dub",
"project": "ebiz_test"
}
属性数据类型
注意问题
发送端使用 JSON 作为数据传输格式,本系统以 JSON 数据类型为基础再加以额外限制,定义了若干种数据类型,但 不与 JSON 类型完全等价,详见后文属性类型说明。
(table_name, property_name) 二元组唯一确定一个属性,table_name 为数据表的表名,如 users、events,可在自定义 SQL 查询中看到。这意味着同表同名属性类型必须相同,而不同表的同名属性类型可以不同。消息类型与所写入的数据表的关系如下表:
消息类型 | 目标数据表 |
track | events |
profile_* | users |
track_signup | 事件信息被写入 events 表,users 表中会记录 first_id 和 second_id |
一个属性的类型由首次导入时的类型决定,元数据-事件属性/用户属性页面展示的属性类型即为首次导入时的类型,后续导入数据时若类型和元数据中展示的类型不符,则尝试对数据进行类型转换,若无法转换或转换失败则 输入数据会被整条拒绝 。尝试进行的类型转换如下(空格不进行转换):
目标类型\原始类型 | 数值型 | 布尔值 | 字符串 | 字符串集合 | 日期时间 |
---|---|---|---|---|---|
数值型 | true -> 1; false -> 0 | 空字符串 "" 抛弃该属性; 其他按数值解析 | |||
布尔值 | 0 -> false; 非 0 值 -> true | 字符串"true"、"false"转换为布尔类型 | |||
字符串 | 原值作为字符串 | 原值作为字符串 | 原值作为字符串 | 原值作为字符串 | |
字符串集合 | |||||
日期时间 | 在一定区间内的按 UNIX 时间戳的秒或毫秒转换 | 多种日期时间格式模式串解析 |
- 上述表格左侧的列对应目标类型,上方的行对应原始类型。目标类型对应元数据中的数据类型,原始类型是数据上传时的属性值类型
- 什么时候该使用数值类型的属性:
- 需要进行聚合运算(例如求和、均值)或者按区间分组的值,典型的比如价格、时长、年龄等。
- 除非有特殊需求,否则各类 ID(例如订单 ID)不建议作为数值类型存储。
神策分析属性数据类型定义
神策分析数据类型 | 中文名 | 基础 JSON 类型 | 额外限制 | 示例 | 说明 |
---|---|---|---|---|---|
NUMBER | 数值型 | number | -9E15 到 9E15 小数点后最多保留3位 | 12 或 12.0 | |
BOOL | 布尔值 | bool | 无 | true 或 false | |
STRING | 字符串 | string | 使用 UTF-8 编码后最大长度 1024 字节 | "SensorsData" | |
LIST | 字符串数组 | list | 1.12 版本之后默认是字符串元素的数组(传入的字符串不会去重),最大元素个数为 500,其中每个元素使用 UTF-8 编码后最大长度 255 字节;注意:1.12 之前的版本,List 是集合,即在入库时会进行重排序和去重。如果需要调整 List 具体是数组还是集合,请联系神策技术支持。若 append 导致超过最大元素个数时,新入库的元素会淘汰最早入库的元素。 | ["橘子","西瓜"] | |
DATETIME | 日期时间 | string | yyyy-MM-dd HH:mm:ss.SSS 或 yyyy-MM-dd HH:mm:ss 或 yyyy-mm-dd (时分秒按00:00:00处理), 建议使用第一种,其中 SSS 为毫秒;年取值范围是 [1900, 2199] | "2015-06-19 17:51:21.234" "2015-06-19 17:51:21" "2015-06-19" | 有些语言的时间格式化库不直接提供毫秒格式化,如 Python 提供 us 而不提供 ms,如需自行编写程序生成数据请注意这点。 |
DATE (仅 <= 1.10 版本) | 日期 | string | 格式为 yyyy-mm-dd,年取值范围是 [1900, 2199] | "2015-06-19" | 自 1.11 版本起,DATE 类型将作为 DATETIME 的一种格式存在(既时分秒为 00:00:00 的 DATETIME,且时分秒可省略),不再单设类型。 |
预置属性
为了帮助使用者更方便地使用我们的产品,我们目前分别为 Event 和 Profile 提供了一些预置字段。
注意:JavaScript SDK 预置属性较多,这里没有全部列出,详细说明请参考相关文档 .Web 预置属性 v1.13
Event 的预置字段有:
字段名称 | 类型 | 说明 | JS SDK 自动采集 | iOS SDK 自动采集 | Android SDK 自动采集 | 小程序 SDK 自动采集 | 服务端 SDK 自动采集 |
---|---|---|---|---|---|---|---|
$app_version | 字符串 | 应用的版本 | N | Y | Y | N | N |
$ip | 字符串 | ip | Y | Y | Y | Y | Y |
$country | 字符串 | 国家 | Y | Y | Y | Y | N |
$city | 字符串 | 城市 | Y | Y | Y | Y | N |
$province | 字符串 | 省份 | Y | Y | Y | Y | N |
$lib | 字符串 | SDK 类型,例如 Python、iOS等 | Y | Y | Y | Y | Y |
$lib_version | 字符串 | SDK 版本 | Y | Y | Y | Y | Y |
$manufacturer | 字符串 | 设备制造商,例如 Apple | Y | Y | Y | N | N |
$model | 字符串 | 设备型号,例如 iPhone 8,4 | Y | Y | Y | Y | N |
$os | 字符串 | 操作系统,例如 iOS | Y | Y | Y | Y | N |
$os_version | 字符串 | 操作系统版本,例如 8.1.1 | Y | Y | Y | Y | N |
$screen_height | 数值 | 屏幕高度,例如 1920 | Y | Y | Y | Y | N |
$screen_width | 数值 | 屏幕宽度,例如 1080 | Y | Y | Y | Y | N |
$wifi | 布尔值 | 是否使用 wifi,例如 true | N | Y | Y | N | N |
$browser | 字符串 | 浏览器名,例如 Chrome | Y | N | Y | N | N |
$browser_version | 字符串 | 浏览器版本,例如 Chrome 45 | Y | N | N | N | N |
$carrier | 字符串 | 运营商名称,例如 ChinaNet | N | Y | Y | N | N |
$network_type | 字符串 | 网络类型,例如 4G | N | Y | Y | Y | N |
$utm_matching_type | 字符串 | 渠道追踪匹配模式 | N | Y1 | Y1 | N | N |
$latest_referrer | 字符串 | 站外前向地址 | Y | N | N | N | N |
$latest_referrer_host | 字符串 | 站外前向域名 | Y | N | N | N | N |
$latest_utm_source | 字符串 | 最近广告系列来源 | Y | N | N | Y5 | N |
$latest_utm_medium | 字符串 | 最近广告系列媒介 | Y | N | N | Y5 | N |
$latest_utm_term | 字符串 | 最近广告系列字词 | Y | N | N | Y5 | N |
$latest_utm_content | 字符串 | 最近广告系列内容 | Y | N | N | Y5 | N |
$latest_utm_campaign | 字符串 | 最近广告系列名称 | Y | N | N | Y5 | N |
$latest_search_keyword | 字符串 | 最近一次搜索引擎关键词 | Y | N | N | N | N |
$latest_traffic_source_type | 字符串 | 最近一次流量来源类型 | Y | N | N | N | N |
$is_first_day | 布尔值 | 是否首日访问 | Y | Y | Y | Y | N |
$device_id | 字符串 | 设备 ID | Y6 | Y | Y | N | N |
Profile 的预置字段有:
字段名称 | 类型 | 说明 | JS SDK 自动采集 | iOS SDK 自动采集 | Android SDK 自动采集 | 小程序 SDK 自动采集 | 服务端 SDK 自动采集 |
---|---|---|---|---|---|---|---|
$city | 字符串 | 用户所在的城市 | N | N | N | N | N |
$province | 字符串 | 用户所在的省份 | N | N | N | N | N |
$name | 字符串 | 用户名 | N | N | N | N | N |
$signup_time | Datetime | 注册时间 | N | N | N | N | N |
$utm_matching_type | 字符串 | 渠道追踪匹配模式 | N | Y1 | Y1 | N | N |
$first_visit_time | Datetime | 首次访问时间 | Y3 | Y4 | Y4 | N | N |
$first_referrer | 字符串 | 首次前向地址 | Y3 | N | N | N | N |
$first_referrer_host | 字符串 | 首次前向域名 | Y3 | N | N | N | N |
$first_browser_language | 字符串 | 首次使用的浏览器语言 | Y3 | N | N | N | N |
$first_browser_charset | 字符串 | 首次浏览器字符类型(1.8支持) | Y3 | N | N | N | N |
$first_search_keyword | 字符串 | 首次搜索引擎关键词(1.8支持) | Y3 | N | N | N | N |
$first_traffic_source_type | 字符串 | 首次流量来源类型(1.8支持) | Y3 | N | N | N | N |
$utm_source | 字符串 | 首次广告系列来源 | Y2 | Y1 | Y1 | Y | N |
$utm_medium | 字符串 | 首次广告系列媒介 | Y2 | Y1 | Y1 | Y | N |
$utm_term | 字符串 | 首次广告系列字词 | Y2 | Y1 | Y1 | Y | N |
$utm_content | 字符串 | 首次广告系列内容 | Y2 | Y1 | Y1 | Y | N |
$utm_campaign | 字符串 | 首次广告系列名称 | Y2 | Y1 | Y1 | Y | N |
Item 的预置字段有:
字段名称 | 类型 | 说明 | SDK 自动采集 |
---|---|---|---|
$is_valid | 布尔值 | 该 item 是否有效,不传入默认为 true | N |
$receive_time | 数值型 | 该 item 到达时间 | Y |
$update_time | 数值型 | 该 item 的更新时间,不传入默认为写入时间 | N |
上述 Y 上标含义如下:
- $utm_ 开头的相关属性,由 App 渠道追踪功能自动采集,请参考相关文档 渠道追踪。
- 新用户首次访问时,需要开启 autoTrack 且 URL 中带有 UTM 参数,才会收集,请参考相关文档 Web JS SDK 。
- 新用户首次访问时,开启 autoTrack 才会收集,请参考相关文档 Web JS SDK。
- 新用户首次启动 App,如果调用了 trackInstallation 接口会自动给这个属性赋值。
- 小程序 SDK 1.3 版本支持。
- 如果 SDK 初始化时候配置了 is_track_device_id:true, 就会采集。
预置属性采集方式
iOS 中,预置属性的采集方式大致如下:
NSMutableDictionary *p = [NSMutableDictionary dictionary];
UIDevice *device = [UIDevice currentDevice];
NSString *deviceModel = [self deviceModel];
struct CGSize size = [UIScreen mainScreen].bounds.size;
CTCarrier *carrier = [[[CTTelephonyNetworkInfo alloc] init] subscriberCellularProvider];
// Use setValue semantics to avoid adding keys where value can be nil.
[p setValue:[[NSBundle mainBundle] infoDictionary][@"CFBundleShortVersionString"] forKey:@"$app_version"];
[p setValue:carrier.carrierName forKey:@"$carrier"];
[p addEntriesFromDictionary:@{
@"$lib": @"iOS",
@"$lib_version": [self libVersion],
@"$manufacturer": @"Apple",
@"$os": [device systemName],
@"$os_version": [device systemVersion],
@"$model": deviceModel,
@"$screen_height": @((NSInteger)size.height),
@"$screen_width": @((NSInteger)size.width),
}];
Android 中,预置属性的采集方式大致如下:
{
deviceInfo.put("$lib", "Android");
deviceInfo.put("$lib_version", VERSION);
deviceInfo.put("$os", "Android");
deviceInfo.put("$os_version",
Build.VERSION.RELEASE == null ? "UNKNOWN" : Build.VERSION.RELEASE);
deviceInfo
.put("$manufacturer", Build.MANUFACTURER == null ? "UNKNOWN" : Build.MANUFACTURER);
deviceInfo.put("$model", Build.MODEL == null ? "UNKNOWN" : Build.MODEL);
try {
final PackageManager manager = mContext.getPackageManager();
final PackageInfo info = manager.getPackageInfo(mContext.getPackageName(), 0);
deviceInfo.put("$app_version", info.versionName);
} catch (final PackageManager.NameNotFoundException e) {
Log.e(LOGTAG, "Exception getting app version name", e);
}
final DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
deviceInfo.put("$screen_height", displayMetrics.heightPixels);
deviceInfo.put("$screen_width", displayMetrics.widthPixels);
TelephonyManager telephonyManager = (TelephonyManager) mContext.getSystemService(Context
.TELEPHONY_SERVICE);
String operatorString = telephonyManager.getSimOperator();
if (operatorString == null) {
// DO NOTHING
} else if (operatorString.equals("46000") || operatorString.equals("46002")) {
deviceInfo.put("$carrier", "中国移动");
} else if (operatorString.equals("46001")) {
deviceInfo.put("$carrier", "中国联通");
} else if (operatorString.equals("46003")) {
deviceInfo.put("$carrier", "中国电信");
} else {
deviceInfo.put("$carrier", "其他");
}
}
导入数据的限制
一般限制
- 事件变量名(event 的值)和 属性变量名(properties 中 key 取值)都需是合法的变量名,即不能以数字开头,且只包含:大小写字母、数字、下划线和 $,且事件变量名和属性变量名最大长度都为 100,自定义的事件名或者属性名不能以$ 开头;
- 变量名不能与已经存在的虚拟事件、虚拟属性的变量名重复;
- 系统对变量名大小写处理有特殊要求,字母完内容完全一致,但是大小写不一致的变量名会被拦截;
- 类型 type 字段的取值只能是上文列出几种(track, profile_set 等),并且大小写敏感;
- 属性 properties 字段必须存在,可以为空( {} );
- 事件 time 字段允许的范围是 1000000000000(2001-09-09 09:46:40) ~ 10000000000000(2286-11-21 01:46:40);
- 自定义的事件或者属性的变量名不可以,本节 1.7.6 列出了保留属性名;
事件时间限制
导入不合理时间的用户事件将影响数据的准确性(如客户端时间错误导致导入未来的数据),故默认情况下对导入的事件时间进行了限制:
- 使用客户端 SDK (iOS、Android)导入的数据,服务端默认只接收事件发生时间在接收时间向前 10 天内和未来向后 1 小时内的数据;
- 使用后端语言 SDK (如 Java、Python 等)或导入工具(如 LogAgent、BatchImporter、HdfsImporter),默认只能导入事件时间当前向前 2 年内和未来向后 1 小时内的数据;
注意:
- 如果希望导入上述默认时间窗口之外的数据,可以联系值班同学修改窗口限制,或在数据中添加 `time_free` 字段(见本文档 2. track 样例)。添加 `time_free` 字段也要保证 time 的格式满足 8.1 节的第 4 点。
- 因为 App 端只能使用客户端的时间作为事件发生的时间,如果客户端时间不准确,会导致采集端数据有异常,因此神策默认开启时间修正机制:App 端发生事件时的时间 time 的值为 t1,发送数据时的时间_flush_time 的值为 t2 (客户端时间,且 _flush_time 不入库),服务端接收到数据的时间 $recive_time 时间为 t3 (服务端时间),如果 |t3-t2|>60s,则认为客户端的时间不准确,会对事件触发时间进行修正,修正后事件时间 t1‘=t1+(t3-t2) 。
以下两种场景不会修正事件发生的时间:- 如果采集事件时客户端时间不准确(即 t1 不准确,比如手机刚开机时间不准),而发送数据时客户端时间是准确的(_flush_time 时间准确,比如开启网络校正时间功能),此时发送到服务端时,由于 |t3-t2|<60s,因此不会对 t1 进行修正。
- 如果数据是延迟上报(比如数据在发送之前用户强杀 App,导致部分数据未及时发送,会先缓存在本地,待下次打开 App,网络正常时会重新尝试发送本地的缓存数据),发送数据时的 _flush_time 时间是准确的,也不会修复事件触发的时间。
显示名相关的限制
- 事件和属性除了有变量名,还会有显示名,方便客户管理事件与属性
- 显示名必须保证和变量名一一对应,不允许出现一对多或者多对一的关系,显示名支持中文、空格、英文、各种符号等字符
同名属性同类型
对 Event 属性,一个属性名,只能具有一种类型(不同的具体事件,同名属性类型也必须相同);
对 Profile 属性,一个属性名,只能具有一种类型;
对于一个属性名,在 Event 和 Profile 中可以具有不同的类型;
属性长度限制
属性的数据类型,及特殊字段长度限制如下:
项目 | 限制 |
---|---|
数据类型 NUMBER | -9E15 到 9E15 小数点后最多保留3位 |
数据类型 STRING | 最大长度 1024 字节 |
数据类型 LIST | 每个 LIST 中最多包含 500 个不大于 255 字节的字符串 |
用户 distinct_id | 最大长度 255 字节 |
用户 original_id | 最大长度 255 字节 |
属性数上限
单个项目 Event / Profile / Item 的属性建议合理设置,过多影响导入和查询性能,达到上限则导致导入异常。
建议值 | 硬上限 |
---|---|
300 以内 | 2000 |
保留字段
为了保证查询时属性名不与系统变量名冲突,设置如下保留字段,请避免其作为事件名和属性名(properties 中的 key)使用:
date
datetime
distinct_id
event
events
event_id
first_id
id
original_id
device_id
properties
second_id
time
user_id
users
user_group 开头
user_tag 开头
注:本文档内容为神策产品使用和技术细节说明文档,不包含适销类条款;具体企业采购产品和技术服务内容,以商业采购合同为准。