數據格式
神策分析支援多種不同語言的 SDK,這些 SDK 雖然在外部提供的介面上有所不同,但是在內部實現上都使用統一的數據格式,並且 數據匯入 都支援直接匯入以檔案形式儲存的符合要求格式的數據,在這裡,我們對數據格式進行一個更加細緻的描述。
- 注意:這裡描述的是底層數據傳輸格式的定義,和具體 SDK 的呼叫介面無關
- 注意:$is_login_id 參數說明
1. 數據整體格式
記錄檔是一行一個 JSON,物理上對應一條數據,邏輯上對應一個描述了用戶行為的事件,或是描述一個或多個用戶屬性的 Profile 操作。
1.1. track:
記錄一個 Event 及關聯的 Properties。
數據樣例:
{
"distinct_id": "123456",
"time": 1434556935000,
"type": "track",
"event": "ViewProduct",
"project": "ebiz_test",
"time_free": true, //建議在匯入歷史數據時使用,SDK 採集的即時數據不建議使用
"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 等,對於登入用戶,則應該填充註冊帳號;這裡的例子,我們假設是一個未註冊用戶,所以填充的是一個裝置編號;
- time:型別是數值,事件發生的實際時間戳,精確到毫秒;
- type:track 表明是記錄一個 Event ,這裡我們假設是一個商品瀏覽行為;
- event:事件名,需是合法的變量名,即不能以數字開頭,且只包含:大小寫字母、數字、下底線和 $,其中以 $ 開頭的表明是系統的保留欄位,自定義事件名請不要以 $ 開頭,且 event 欄位長度最大為 100;
- project:這條數據所屬專案名,若不指定該參數,則需要使用該欄位時取值 default,即預設專案。指定的專案必須是系統中已經存在的專案,否則這條數據將無效,更多專案相關請參見多專案;
- time_free:可選欄位,表示不根據事件發生時間過濾該事件。只要出現 time_free 這個 key 且 value 不為 null,將不再校驗 time 是否在允許匯入的時間範圍內。匯入歷史數據時可能會用到該欄位;
- properties:這個 Event 的具體屬性,以 dict 的形式存在。其中以$開頭的表明是系統的保留欄位,它的型別和中文名已經預先定義好了。自定義屬性名需要是合法的變量名,不能以數字開頭,且只包含:大小寫字母、數字、下底線,自定義屬性不能以 $ 開頭;同一個名稱的 property,在不同 event 中,必須保持一致的定義和型別;同一個名稱的 property 大小寫不可以相同,如果已經存在小寫屬性就不可再匯入對應大寫屬性(比如元數據中有 abc 屬性名,不能再傳 ABC,Abc 等屬性名),否則數據會校驗失敗不入庫。
- $is_login_id:distinct_id 對應的是否是一個註冊 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:跟商品相關的一些具體屬性。
1.2. track_signup:
這個介面是一個較為複雜的功能,請在使用前先閱讀 標識用戶,並在必要時聯繫我們的技術支援人員。
數據樣例:
{
"distinct_id":"12345",
"original_id":"2b0a6f51a3cd6775",
"time": 1434557935000,
"type": "track_signup",
"event": "$SignUp",
"project": "ebiz_test",
"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 為 2b0a6f51a3cd6775 的用戶,成功完成了註冊,註冊後的註冊 ID 是 12345。並且系統後台,會將 original_id 為 2b0a6f51a3cd6775 的用戶和 distinct_id 為 12345 的用戶,當做同一個用戶對待。需要注意的是,此介面中的 original_id 為必須欄位,表示與註冊 ID 進行關聯的匿名 ID。
1.3. Profile 相關操作
Profile 相關操作,主要是用來設定用戶的 Profile 的,提供了如下一系列介面:
1.3.1. profile_set:
直接設定一個用戶的 Profile,如果用戶或者 Profile 的欄位已存在,則覆蓋,不存在則自動建立。
數據樣例:
{
"distinct_id": "12345",
"type": "profile_set",
"time": 1435290195610,
"project": "ebiz_test",
"properties": {
"$province":"湖南",
"FavoriteFruits": ["蘋果","香蕉","芒果"],
"Age":33,
"$city":"長沙",
"IncomeLevel": "3000~5000",
"$name": "小明",
"Gender":"男",
"$signup_time": "2015-06-26 11:43:15.610"
}
}
1.3.2. profile_set_once
直接設定一個用戶的 Profile。與 profile_set 介面不同的是,如果用戶或者 Profile 的欄位已存在,則這條記錄會被忽略而不會覆蓋已有數據,如果 Profile 不存在則會自動建立。因此,profile_set_once 比較適用於為用戶設定首次啟動時間、首次註冊時間等只在首次設定時有效的屬性。
數據樣例:
{
"distinct_id": "12345",
"type": "profile_set_once",
"time": 1435290195610,
"project": "ebiz_test",
"properties": {
"$province":"湖南",
"FavoriteFruits": ["蘋果","香蕉","芒果"],
"Age":33,
"$city":"長沙",
"IncomeLevel": "3000~5000",
"$name": "小明",
"Gender":"男",
"$signup_time": "2015-06-26 11:43:15.610"
}
}
}
1.3.3. profile_increment:
增加或減少一個用戶的某個 NUMBER 型別的 Profile 值,比如給用戶屬性 Age 的值加 1 或者減 1 。如果用戶表( users 表)中不存在這個用戶,則會在用戶表中自動建立該用戶的 id 記錄,並給該用戶設定相應的 Profile 屬性值,會在預設值 0 的基礎上增加上傳的 Profile 值。
數據樣例:
{
"distinct_id": "12345",
"type": "profile_increment",
"time": 1435290200354,
"project": "ebiz_test",
"properties": {
"Age": 1
}
}
1.3.4. profile_delete:
刪除一個用戶的整個 Profile。
數據樣例:
{
"distinct_id": "12345",
"type": "profile_delete",
"time": 1437290200354,
"project": "ebiz_test",
"properties":{
}
}
1.3.5. profile_append:
向某個用戶的某個數組型別的 Profile 增加一個或者多個值。如果本次上傳的值,與系統中已存在的值有重複,預設是不會去重的。如果本次上傳的值,有重複項,也不會去重的。
數據樣例:
{
"distinct_id": "12345",
"type": "profile_append",
"time": 1437280200354,
"project": "ebiz_test",
"properties": {
"FavoriteFruits": ["橘子","西瓜"]
}
}
1.3.6. profile_unset:
將某個用戶的某些屬性值設定為空。另外,為了與其它介面保持一致,在提交的數據上,屬性的值請設定為非 null 的任何值,例如 true。
數據樣例:
{
"distinct_id":"12345",
"type":"profile_unset",
"time":1437280200354,
"project": "ebiz_test",
"properties":{
"Age":true,
"FavoriteFruits":true
}
}
1.4. Item 相關操作
Item 相關操作,主要是用來設定 Item 的具體內容,提供了如下一系列介面:
1.4.1. 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 的形式存在。屬性名需要是合法的變量名,不能以數字開頭,且只包含:大小寫字母、數字、下底線;
1.4.2. item_delete:
刪除整個 Item 內容。
數據樣例:
{
"type":"item_delete",
"item_id":"16",
"item_type":"dub",
"project": "ebiz_test"
}
1.5. 屬性數據型別
1.5.1. 注意問題
發送端使用 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)不建議作為數值型別儲存。
1.5.2. 神策分析屬性數據型別定義
神策分析數據型別 | 中文名 | 基礎 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 或 | "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, 2099] | "2015-06-19" | 自 1.11 版本起,DATE 型別將作為 DATETIME 的一種格式存在(既時分秒為 00:00:00 的 DATETIME,且時分秒可省略),不再單設型別。 |
1.6. 預設屬性
為了幫助使用者更方便地使用我們的產品,我們目前分別為 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, 就會採集。
1.6.1. 預設屬性採集方式
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", "其他");
}
}
1.7. 數據導入的限制
1.7.1. 一般限制
- 事件名(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 列出了保留屬性名;
1.7.2. 事件時間限制
匯入不合理時間的用戶事件將影響數據的準確性(如客戶端時間錯誤導致匯入未來的數據),故預設情況下對匯入的事件時間進行了限制:
- 使用客戶端 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 時間是準確的,也不會修復事件觸發的時間。
1.7.3. 顯示名相關的限制
- 事件和屬性除了有變量名,還會有顯示名,方便客戶管理事件與屬性
- 顯示名必須保證和變量名一一對應,不允許出現一對多或者多對一的關係,顯示名支持中文、空格、英文、各種符號等字符
1.7.4. 同名屬性同型別
對 Event 屬性,一個屬性名,只能具有一種型別(不同的具體事件,同名屬性型別也必須相同);
對 Profile 屬性,一個屬性名,只能具有一種型別;
對於一個屬性名,在 Event 和 Profile 中可以具有不同的型別;
1.7.5. 屬性長度限制
屬性的數據型別,及特殊欄位長度限制如下:
項目 | 限制 |
---|---|
數據型別 NUMBER | -9E15 到 9E15 小數點後最多保留3位 |
數據型別 STRING | 最大長度 1024 位元組 |
數據型別 LIST | 每個 LIST 中最多包含 500 個不大於 255 位元組的字串 |
用戶 distinct_id | 最大長度 255 位元組 |
用戶 original_id | 最大長度 255 位元組 |
1.7.6. 屬性數上限
單個專案 Event / Profile 的屬性建議合理設定,過多影響匯入和查詢性能,達到上限則導致匯入異常。
建議值 | 上限值 |
---|---|
300 以内 | 2000 |
1.7.7. 保留欄位
為了保證查詢時屬性名不與系統變量名衝突,設定如下保留欄位,請避免其作為事件名和屬性名(properties 中的 key)使用:
date
datetime
distinct_id
event
events
first_id
id
original_id
device_id
properties
second_id
time
user_id
users
user_group 開頭
user_tag 開頭
1.8. 常見問題
1.8.1. $is_login_id 參數說明
常見使用場景:歷史數據匯入的 events 或者 users 數據,伺服器端 SDK 的 track 或 profile 介面。
屬性值含義:true ,表示這條數據中的 distinct_id 欄位的值為一個真實的 ID(例如客戶的業務 ID),如果在這條數據進入數據庫之前,此真實 ID 未和裝置 ID 綁定,(綁定操作,前端可參考 login 方法,以 JavaScript SDK 為例,在登入和註冊成功後,呼叫 sensor.login(userid); 來標識真實用戶。伺服器端可參考 tracksignup 方法,以 Java SDK 為例,歷史數據匯入可參考本文件的 tracksignup 介面。),那麼這個真實 ID 會自關聯。兩種情況:
- 如果開啟了多對一(多對一)的話,新的裝置 ID 還是可以和這個自關聯的真實 ID 關聯。
- 在未開啟多對一的情況下導致這個真實 ID 之後不能再和裝置 ID 綁定。
屬性值含義:false,表示這條數據中的 distinct_id 欄位的值為一個裝置 ID(即客戶註冊登入之前的標識用戶的 ID),之後此裝置 ID 還可以和一個真實 ID 綁定。