概述
达观数据为应用方提供了功能强大、使用灵活的智能推荐、垂直搜索、流量分析等大数据服务,数据上报是接入达观服务的基础和前提条件,请将待推荐、待搜索的产品信息,用户在网站的行为数据通过达观数据上报接口上传到达观服务器。
数据上报采用简单易用的HTTP接口,应用方可以根据各自的业务场景选择离线批量或者实时导入。数据上报也支持gzip压缩数据,具体请参考本文档最后的示例代码。
达观预定义了多个数据表,用以存储产品信息数据、产品行为数据等,请严格按照本文档各个数据表的字段定义,进行数据上报。
注意事项
您需要完成以下步骤后,才可调用达观数据相关服务。
1. 如您还没有开通达观账号,请先开通,账号开通请参考文档:Step 1:开通账号。
2. 获取您的appid
及appname
,请参考文档:获取AppId及AppName。
3. 设置IP白名单,请参考文档:设置IP白名单。
4. 如果您使用智能推荐
或搜索引擎
服务,请先进行数据上报。数据上报请参考文档:数据上报接口文档。
5. 数据上报成功后,可以登录达观大数据平台查看,数据上报到显示会有两三分钟的延迟。
常见问题
1.常见问题及解答请参考数据上报常见问题。
2.强烈建议
使用本文档末尾提供的代码进行数据上报,可以避免大部分问题
。
接口列表
数据上报
接口描述
达观数据上报统一接口,产品信息数据、用户信息数据、用户行为数据等都是通过该接口进行上报。不管是接入达观推荐服务、搜索服务还是数据分析服务,首先都需要进行数据上报
。
URL
http://datareportapi.datagrand.com/data/YOUR_APP_NAME
* 注:YOUR_APP_NAME
请填您的达观账号名。
Http Method
POST
Http 返回格式
JSON
Http 请求参数说明
参数 | 类型 | 是否必需 | 描述 |
---|---|---|---|
appid | int | 是 | 您的达观账号对应的id |
table_name | string | 是 | 要上传数据的表名 |
table_content | string | 是 | 上报的数据内容,JSON格式 |
请求参数详细说明:
1. table_name
table_name字段表明数据所要上传到的表格。达观预定义了4个数据表,table_name字段 只能是以下表格中给出的值
。请对照各个表格的含义,上传数据到正确的表格。
各个达观数据表格和字段的详细说明,请参见后文“上报数据表详细说明”。
table_name | 含义 |
---|---|
item | 物品信息表 |
user | 用户信息表 |
user_action | 用户行为信息表 |
recshow | 推荐结果表 |
2. table_content
table_content字段的值对应的是上报的数据内容,必须是UTF8编码
。
支持批量上报,即一次请求上报多条数据,因此table_content是一个列表(list)的JSON字符串
。
table_content列表的每一个元素是一个字典(dict)格式的数据包
,一个数据包对应一条数据记录,每个数据包必须包含“cmd”和“fields”两个字段
。
(1)cmd可能的取值和定义如下:
cmd | 含义 |
---|---|
add | 新增一条记录,如果主键对应的记录已经存在,则对该记录做覆盖 操作 |
delete | 删除一条记录,如果主键对应的记录不存在,则认为删除成功,user_action和recshow表不支持delete操作 |
refresh_all | 批量下线item数据,仅对item表有效 |
(2)fields 字段的值为一个词典(dict),是具体上报的数据内容,请将您所要上报的字段及相应的值构建成词典,比如 { “itemid”: “28394556”, “cateid”: “9_2_1”, “score”: 459, “title”: “天穿修炼记最新版”, “item_tags”: “修仙”}。
注:根据上报的table_name的不同,**fields** 应包含不同的字段,详见后文“**上报数据表详细说明**”。
Http 返回结果说明
参数 | 类型 | 描述 |
---|---|---|
status | string | 执行结果,OK为成功 ,FAIL为失败 ,WARN为有部分非重要字段异常 ,请根据返回错误信息进行排查。 |
errors | string | 错误信息 |
request_id | int | 该条上报记录的序号,仅用于排查问题使用 |
上报数据表详细说明
概述
达观预定义了4个数据表格,以下给出每个表格的字段定义,以及取值的格式,请严格按照以下规定进行数据上报。
如果上报的数据字段和以下数据表的字段含义不一致,请务必按照本文档规定的字段名进行上报,否则可能会影响搜索、推荐等功能的效果
。
item(物品信息表)
说明: 用于上报主要的产品数据,比如商品信息、视频信息、主播信息等等。
参数 | 类型 | 必需 | 描述 |
---|---|---|---|
itemid | string | 是 |
item的唯一id |
cateid | string | 否 | cateid ,item所属分类,多级分类用“_”进行分隔。例如“1_2”,表示一级分类为1,二级分类为2。如果同时属于多个分类,用英文分号“;”分隔。比如“1_2;3_1”。 |
score | int | 否 | item的热门程度,0~1000的整数 |
title | string | 否 | item的标题 |
content | string | 否 | 正文,比如帖子或新闻的正文 |
price | int | 否 | item的价格,单位为分 |
item_tags | string | 否 | item的标签等信息,多个标签以英文分号“;” 分割。使用推荐功能的客户可上传该字段以提高推荐准确率;如果需要根据标签进行搜索,此项也需要填上 。 |
item_modify_time | int | 否 | item的最新修改时间,unix时间戳,精确到秒 。使用推荐功能的客户可上传该字段以提高推荐时效性;如果需要根据该字段进行搜索筛选,则此项需要填上 。 |
其他 | string | 否 | 其他字段也可以进行上报,如果有时间字段,需要采用unix时间戳(精确到秒) |
注意事项
1. item_modify_time必须是秒级的时间戳,不是毫秒
2. cateid不要错写成cate
3. cateid和item_tags必须使用英文分号分隔,不能用逗号(中英文)或者其它
示例
CURL调用示例
:
Content-Type: multipart/form-data方式:
1 2 |
curl -i -X POST -d 'appid=YOUR_APP_ID&table_name=item&table_content=[{"cmd":"add", "fields": { "itemid": "28394556", "cateid": "9_2_1", "score": 459, "title": "天穿修炼记最新版", "item_tags": "修仙"}}, {"cmd":"add", "fields": { "itemid": "28394557", "cateid": "9_2_1", "score": 434, "title": "比利林恩的中场战事", "item_tags": "战争"}}]' 'http://datareportapi.datagrand.com/data/YOUR_APP_NAME' |
Content-Type: application/json方式:
1 2 |
curl -i -X POST -H "Content-Type: application/json" -d '{"appid":YOUR_APP_ID, "table_name" : "item", "table_content": [{"cmd":"add", "fields": {"itemid": "28394556", "cateid": "9_2_1", "score": 459, "title": "天穿修炼记最新版", "item_tags": "修仙"}}, {"cmd":"add", "fields": { "itemid": "28394557", "cateid": "9_2_1", "score": 434, "title": "比利林恩的中场战事", "item_tags": "战争"}}]}' 'http://datareportapi.datagrand.com/data/YOUR_APP_NAME' |
refresh_all调用示例
:
注意:
1. refresh_all命令需要在fields中填all_itemid,all_itemid是所有要保持在线
的itemid构成的list,refresh_all会把不在all_itemid中的所有item
都下线,请谨慎使用!
2. all_itemid必须传多于100个itemid
1 2 |
curl -i -X POST -d 'appid=YOUR_APP_ID&table_name=item&table_content=[{"cmd":"refresh_all", "fields": {"all_itemid": ["28394556","23423423"]}}]' 'http://datareportapi.datagrand.com/data/YOUR_APP_NAME' |
成功返回示例
:
1 2 3 4 5 |
{ "status":"OK", "request_id":148642065805100373587 } |
错误返回示例
:
1 2 3 4 5 6 7 8 9 |
{ "status":"FAIL", "errors":{ "code":1012, "message":"table does not exist" }, "request_id":142234873908422234072 } |
警告返回示例
1 2 3 4 5 6 7 8 9 |
{ "status":"WARN", "errors":{ "code":8012, "message":"sex value is incorrect" }, "request_id":142234873908422234072 } |
user_action(用户行为信息表)
说明: 用户的行为数据,尤其是对物品的比较重要的行为数据,比如购买。
* 接入搜索和推荐功能的话,用户对搜索结果和推荐结果的点击行为也通过该表进行上报。
参数 | 类型 | 必需 | 描述 |
---|---|---|---|
userid | string | 否 | 用户唯一id,对应user表的userid |
imei | string | 否 | 用户的手机IMEI号 |
cid | string | 否 | 用户的cookieid,(userid、imei、cid至少存在一个) |
itemid | string | 否 | 对应item表的itemid |
action_type | string | 是 |
用户对item执行的操作,必须是有意义的字符串 |
action_num | int | 否 | 动作数量。对于购买,可以是购买价格(单位为分) |
action_detail | string | 否 | 该行为的一些描述信息,该字段可以自行定义,比如登录的话,可以是qq登录或者微信登录,发送短信可以是短信发送成功或者失败等等。在大数据平台会对这些数据进行汇总,以;进行分隔 |
timestamp | timestamp | 否 | 动作发生的时间,linux时间戳,精确到秒 ,必须是最近一周以内的时间 ,没有传则置为收到请求的时间 |
其他 | string | 否 | 其他字段也可以进行上报,如果有时间字段,需要采用unix时间戳(精确到秒) |
常用的的action_type如下表所示:
action_type | 含义 |
---|---|
view | 浏览 |
search_click | 点击搜索结果 |
rec_click | 点击推荐结果 |
collect | 收藏 |
subscribe | 订阅 |
comment | 评论 |
gift | 送礼物 |
share | 分享 |
like | 点赞 |
dislike | 点衰 |
cart | 加入购物车(或加入书架) |
buy | 购买 |
注意事项
1. 上报用户浏览、点击行为时,上报的itemid不能为空
2. userid imei cid三个用户至少有一个不能为空
3. timestamp必须是秒级的时间戳,不是毫秒
4. action_type必须是有意义的字符串,如果用户的操作是上面表格所列的动作,请按照表格规定进行上报
示例
CURL调用示例
Content-Type: multipart/form-data方式:
1 2 |
curl -i -X POST -d 'appid=YOUR_APP_ID&table_name=user_action&table_content=[{"cmd":"add", "fields":{"timestamp":1489040079, "action_type":"view", "userid": "1234", "itemid": "abc12"}}]' 'http://datareportapi.datagrand.com/data/YOUR_APP_NAME' |
Content-Type: application/json方式:
1 2 |
curl -i -X POST -H "Content-Type: application/json" -d '{"appid":YOUR_APP_ID, "table_name" : "user_action", "table_content": [{"cmd":"add", "fields":{"timestamp":1489040079, "action_type":"view", "userid": "1234", "itemid": "abc12"}}]}' 'http://datareportapi.datagrand.com/data/YOUR_APP_NAME' |
HTTP请求示例代码
JAVA
1. 普通方式上传
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
package com.datagrand.datareport.test; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.Map.Entry; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.NameValuePair; import org.apache.http.StatusLine; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.entity.GzipDecompressingEntity; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.message.BasicNameValuePair; import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpParams; import org.apache.http.util.EntityUtils; @SuppressWarnings("deprecation") public class TestHttp{ @SuppressWarnings("resource") public String post(String reqURL, Map<String, String> params) throws ClientProtocolException, IOException{ String responseContent = ""; HttpPost httpPost = new HttpPost(reqURL); if (params != null) { List nvps = new ArrayList(); Set<Entry<String, String>> paramEntrys = params.entrySet(); for (Entry<String, String> entry : paramEntrys) { nvps.add(new BasicNameValuePair(entry.getKey(), entry.getValue())); } httpPost.setEntity(new UrlEncodedFormEntity(nvps, "utf-8")); } httpPost.setHeader("User-Agent", "datagrand/datareport/java sdk v1.0.0"); httpPost.setHeader("Content-Type","application/x-www-form-urlencoded"); HttpClient httpClient = new DefaultHttpClient(); HttpParams httpParams = httpClient.getParams(); HttpConnectionParams.setSoTimeout(httpParams, 60*1000); HttpConnectionParams.setConnectionTimeout(httpParams, 60*1000); HttpResponse response = httpClient.execute(httpPost); StatusLine status = response.getStatusLine(); if (status.getStatusCode() >= HttpStatus.SC_MULTIPLE_CHOICES) { System.out.printf( "Did not receive successful HTTP response: status code = {}, status message = {}", status.getStatusCode(), status.getReasonPhrase()); httpPost.abort(); } HttpEntity entity = response.getEntity(); if (entity != null) { responseContent = EntityUtils.toString(entity, "utf-8"); EntityUtils.consume(entity); } else { System.out.printf("Http entity is null! request url is {},response status is {}", reqURL, response.getStatusLine()); } return responseContent; } public static void main(String[] args){ TestHttp obj = new TestHttp(); Map<String,String> params = new HashMap<String,String>(); params.put("appid", "237389"); params.put("table_name", "item"); String table_content = "[{\"cmd\":\"add\",\"fields\":{\"itemid\":\"10001\"}}]"; params.put("table_content", table_content); String res; try { res = obj.post("http://datareportapi.datagrand.com/data/your_app_name", params); System.out.println(res); } catch (Exception e) { e.printStackTrace(); } } } |
2. gzip压缩上传
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
package com.datagrand.datareport.test; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.zip.GZIPOutputStream; import java.util.Map.Entry; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.NameValuePair; import org.apache.http.StatusLine; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.entity.GzipCompressingEntity; import org.apache.http.client.entity.GzipDecompressingEntity; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.ByteArrayEntity; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.message.BasicNameValuePair; import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpParams; import org.apache.http.util.EntityUtils; @SuppressWarnings("deprecation") public class TestHttp{ @SuppressWarnings("resource") public String post(String reqURL, Map<String, String> params) throws ClientProtocolException, IOException{ String responseContent = ""; HttpPost httpPost = new HttpPost(reqURL); if (params != null) { List<NameValuePair> nvps = new ArrayList<NameValuePair>(); Set<Entry<String, String>> paramEntrys = params.entrySet(); for (Entry<String, String> entry : paramEntrys) { nvps.add(new BasicNameValuePair(entry.getKey(), entry.getValue())); } UrlEncodedFormEntity entity = new UrlEncodedFormEntity(nvps, "utf-8"); httpPost.setEntity(new GzipCompressingEntity(entity)); } httpPost.setHeader("User-Agent", "datagrand/datareport/java sdk v1.0.0"); httpPost.setHeader("Content-Type","application/x-www-form-urlencoded"); httpPost.setHeader("Content-Encoding","gzip"); HttpClient httpClient = new DefaultHttpClient(); HttpParams httpParams = httpClient.getParams(); HttpConnectionParams.setSoTimeout(httpParams, 60*1000); HttpConnectionParams.setConnectionTimeout(httpParams, 60*1000); HttpResponse response = httpClient.execute(httpPost); StatusLine status = response.getStatusLine(); if (status.getStatusCode() >= HttpStatus.SC_MULTIPLE_CHOICES) { System.out.printf( "Did not receive successful HTTP response: status code = {}, status message = {}", status.getStatusCode(), status.getReasonPhrase()); httpPost.abort(); } HttpEntity entity = response.getEntity(); if (entity != null) { responseContent = EntityUtils.toString(entity, "utf-8"); EntityUtils.consume(entity); } else { System.out.printf("Http entity is null! request url is {},response status is {}", reqURL, response.getStatusLine()); } return responseContent; } public static void main(String[] args){ TestHttp obj = new TestHttp(); Map<String,String> params = new HashMap<String,String>(); params.put("appid", "237389"); params.put("table_name", "item"); String table_content = "[{\"cmd\":\"add\",\"fields\":{\"itemid\":\"10001\"}}]"; params.put("table_content", table_content); String res; try { res = obj.post("http://datareportapi.datagrand.com/data/mytest1", params); System.out.println(res); } catch (Exception e) { e.printStackTrace(); } } } |
PHP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
<?php function reportItemsByCurl($url, $params = array()) { $options = array( CURLOPT_HTTP_VERSION => 'CURL_HTTP_VERSION_1_1', CURLOPT_CONNECTTIMEOUT => 60, CURLOPT_TIMEOUT => 60, CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_HEADER => false, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER =>array('Expect:'), CURLOPT_POSTFIELDS => $params, ); $session = curl_init($url); curl_setopt_array($session, $options); $response = curl_exec($session); curl_close($session); return $response; } $jsondata = array( 'cmd'=>'add', 'fields'=>array( 'itemid'=>'1111', 'title'=>'title', 'cateid'=>'1' ) ); $content = array(); array_push($content, $jsondata); $YOUR_APP_ID = 237389; $data = array( 'appid'=>$YOUR_APP_ID, 'table_name'=>'item', 'table_content'=> json_encode($content) ); $returnDG = reportItemsByCurl('http://datareportapi.datagrand.com/data/YOUR_APP_NAME', $data); echo $returnDG; |