神策分析支援多種不同語言的 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
    }
}
CODE


對於上述欄位的說明如下:

  • 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
    }
}
CODE


這條數據表示,一個匿名 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"
    }
}
CODE

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"
    }
}
}
CODE

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
	}
}
CODE

1.3.4. profile_delete:

刪除一個用戶的整個 Profile。

數據樣例:

{
	"distinct_id": "12345",
	"type": "profile_delete",
	"time": 1437290200354,
	"project": "ebiz_test",
	"properties":{
	}
}
CODE

1.3.5. profile_append:

向某個用戶的某個數組型別的 Profile 增加一個或者多個值。如果本次上傳的值,與系統中已存在的值有重複,預設是不會去重的。如果本次上傳的值,有重複項,也不會去重的。

數據樣例:

{
	"distinct_id": "12345",
	"type": "profile_append",
	"time": 1437280200354,
	"project": "ebiz_test",
	"properties": {
		"FavoriteFruits": ["橘子","西瓜"]
	}
}
CODE

1.3.6.  profile_unset:

將某個用戶的某些屬性值設定為空。另外,為了與其它介面保持一致,在提交的數據上,屬性的值請設定為非 null 的任何值,例如 true。

數據樣例:

{
	"distinct_id":"12345",
	"type":"profile_unset",
	"time":1437280200354,
	"project": "ebiz_test",
	"properties":{
		"Age":true,
		"FavoriteFruits":true
	}
}
CODE

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"
	}
}
CODE

對上述欄位的解釋如下:

  • 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"
}
CODE

1.5. 屬性數據型別

1.5.1. 注意問題

發送端使用 JSON 作為數據傳輸格式,本系統以 JSON 數據型別為基礎再加以額外限制,定義了若干種數據型別,但 不與 JSON 型別完全等價,詳見後文屬性型別說明。

(table_name, property_name) 二元組唯一確定一個屬性,table_name 為數據表的表名,如 users、events,可在自定義 SQL 查詢中看到。這意味著同表同名屬性型別必須相同,而不同表的同名屬性型別可以不同。消息型別與所寫入的數據表的關係如下表:  

消息型別目標數據表
trackevents
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布林值booltrue 或 false
STRING字串string使用 UTF-8 編碼後最大長度 1024 位元組,如需調整最大長度可以聯繫我們"SensorsData"
LIST字串陣列list1.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, 2099]

"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字串

應用的版本

NYYNN
$ip字串ipYYYYY
$country字串

國家

YYYYN
$city字串城市YYYYN
$province字串省份YYYYN
$lib字串SDK 型別,例如 Python、iOS等YYYYY
$lib_version字串SDK 版本YYYYY
$manufacturer字串裝置製造商,例如 AppleYYYNN
$model字串裝置型號,例如 iPhone 8,4YYYYN
$os字串作業系統,例如 iOSYYYYN
$os_version字串作業系統版本,例如 8.1.1YYYYN
$screen_height數值螢幕高度,例如 1920YYYYN
$screen_width數值螢幕宽度,例如 1080YYYYN
$wifi布林值是否使用 wifi,例如 trueNYYNN
$browser字串瀏覽器名,例如 ChromeYNYNN
$browser_version字串瀏覽器版本,例如 Chrome 45YNNNN
$carrier字串營運商名稱,例如 ChinaNetNYYNN
$network_type字串網絡類型,例如 4GNYYYN
$utm_matching_type字串

管道追蹤匹配模式

NY1Y1NN
$latest_referrer字串站外前向網址YNNNN
$latest_referrer_host字串站外前向域名YNNNN
$latest_utm_source字串最近廣告系列來源YNNY5N
$latest_utm_medium字串最近廣告系列媒介YNNY5N
$latest_utm_term字串最近廣告系列字詞YNNY5N
$latest_utm_content字串最近廣告系列内容YNNY5N
$latest_utm_campaign字串最近廣告系列名稱YNNY5N
$latest_search_keyword字串最近一次搜尋引擎關鍵字YNNNN
$latest_traffic_source_type字串最近一次流量來源類型YNNNN
$is_first_day布尔值是否首日訪問YYYYN
$device_id字串裝置 IDY6YYNN

Profile 的預設欄位有:

欄位名稱型別說明JS SDK 自動採集iOS SDK 自動採集Android SDK 自動採集小程序 SDK 自動採集伺服器端 SDK 自動採集
$city字串用戶所在的城市NNNNN
$province字串用戶所在的省份NNNNN
$name字串用戶名NNNNN
$signup_timeDatetime

註冊時間

NNNNN
$utm_matching_type字串

管道追蹤匹配模式

NY1Y1NN
$first_visit_timeDatetime

首次訪問時間

Y3Y4Y4NN
$first_referrer字串首次前向網址Y3NNNN
$first_referrer_host字串首次前向域名Y3NNNN
$first_browser_language字串首次使用的瀏覽器語言Y3NNNN
$first_browser_charset字串首次瀏覽器字元型別(1.8支援)Y3NNNN
$first_search_keyword字串首次搜尋引擎關鍵字(1.8支援)Y3NNNN
$first_traffic_source_type字串首次流量來源類型(1.8支援)Y3NNNN
$utm_source字串首次廣告系列來源Y2Y1Y1YN
$utm_medium字串首次廣告系列媒介Y2Y1Y1YN
$utm_term字串首次廣告系列字词Y2Y1Y1YN
$utm_content字串首次廣告系列内容Y2Y1Y1YN
$utm_campaign字串首次廣告系列名稱Y2Y1Y1YN

Item 的預設欄位有:

欄位名稱型別說明SDK 自動採集
$is_valid布林值該 item 是否有效,不傳入預設為 trueN
$receive_time數值型該 item 到達時間Y
$update_time數值型該 item 的更新時間,不傳入預設為寫入時間N

上述 Y 上標含義如下:

  1. $utm_ 開頭的相關屬性,由 App 管道追蹤功能自動採集,請參考相關文件 渠道追蹤
  2. 新用戶首次訪問時,需要開啟 autoTrack 且 URL 中帶有 UTM 參數,才會收集,請參考相關文件 Web JS SDK
  3. 新用戶首次訪問時,開啟 autoTrack 才會收集,請參考相關文件 Web JS SDK
  4. 新用戶首次啟動 App,如果呼叫了 trackInstallation 介面會自動給這個屬性賦值。
  5. 小程序 SDK 1.3 版本支援。
  6. 如果 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),
                                    }];
CODE

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", "其他");
    }
  }
JAVA

1.7. 數據導入的限制

1.7.1. 一般限制

  1. 事件名(event 的值)和 屬性名(properties 中 key 取值)都需是合法的變量名,即不能以數字開頭,且只包含:大小寫字母、數字、下底線和 $,且事件名和屬性名最大長度都為 100;
  2. 類型 type 欄位的取值只能是上文列出幾種(track, profile_set 等),並且大小寫敏感;
  3. 屬性 properties 欄位必須存在,可以為空( {} );
  4. 事件 time 欄位允許的範圍是 1000000000000(2001-09-09 09:46:40) ~ 10000000000000(2286-11-21 01:46:40);
  5. 本節 1.7.6 列出了保留屬性名; 

1.7.2. 事件時間限制

匯入不合理時間的用戶事件將影響數據的準確性(如客戶端時間錯誤導致匯入未來的數據),故預設情況下對匯入的事件時間進行了限制: 

  1. 使用客戶端 SDK (iOS、Android)匯入的數據,伺服器端預設只接收事件發生時間在接收時間向前 10 天內和未來向後 1 小時內的數據; 
  2. 使用後端語言 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. 事件和屬性除了有變量名,還會有顯示名,方便客戶管理事件與屬性
  2. 顯示名必須保證和變量名一一對應,不允許出現一對多或者多對一的關係,顯示名支持中文、空格、英文、各種符號等字符

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 開頭
CODE

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 會自關聯。兩種情況:

  1. 如果開啟了多對一(多對一)的話,新的裝置 ID 還是可以和這個自關聯的真實 ID 關聯。
  2. 在未開啟多對一的情況下導致這個真實 ID 之後不能再和裝置 ID 綁定。 

屬性值含義:false,表示這條數據中的 distinct_id 欄位的值為一個裝置 ID(即客戶註冊登入之前的標識用戶的 ID),之後此裝置 ID 還可以和一個真實 ID 綁定。