将 Keenio 提取 API 查询数据解析为 google 电子表格
Parsing Keenio Extraction API query data into google spreadsheet
如何解析这样的 JSON?这是要提取到 Google 电子表格中的 Keenio 提取 API 查询数据。
我尝试使用以下代码解析返回的 JSON,但不知道如何访问嵌套对象和数组。
function myFunction() {
var URL = "https://api.keen.io/3.0/projects/" +
PROJECT_KEY + "/queries/extraction?api_key=" +
API_KEY + "&event_collection=" +
EVT_COL + "&timezone=" +
TIMEZONE + "&latest=" +
LATEST + "&property_names.........."
var response = UrlFetchApp.fetch(URL);
var json = response.getContentText();
var rawdata = JSON.parse(response.getContentText());
Logger.log(rawdata.result);
var data = [];
data.push(rawdata.result);
SpreadsheetApp.getActiveSheet().appendRow(data);
}
上面我写的简单函数来解析这个JSON,但是我无法使用点表示法获取嵌套对象和数组。
我在使用著名的 IMPORTJSON 代码时观察到的另一件事是,每次出现时列的顺序都会打乱,所以我在返回数据上写的公式,用于导致参考错误。
{
"result": [
{
"sg_event_id": "92-OndRfTs6fZjNdHWzLBw",
"timestamp": 1529618395,
"url": "https://noname.com?utm_campaign=website&utm_source=sendgrid.com&utm_medium=email",
"ip": "192.168.1.1",
"event": "click",
"keen": {
"timestamp": "2018-06-21T21:59:55.000Z",
"created_at": "2018-06-21T22:00:28.532Z",
"id": "555c1f7c5asdf7000167d87b"
},
"url_offset": {
"index": 38,
"type": "text"
},
"sg_message_id": "F5mwV1rESdyKFA_2bn1IEQ.filter0042p3las1-15933-5B2A68E8-36.0",
"useragent": "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)",
"email": "no.name@noname.com"
}, {
"sg_event_id": "bjMlfsSfRyuXEVy8LndsYA",
"timestamp": 1529618349,
"url": "https://noname.com?utm_campaign=website&utm_source=sendgrid.com&utm_medium=email",
"ip": "192.168.1.1",
"event": "click",
"keen": {
"timestamp": "2018-06-21T21:59:09.000Z",
"created_at": "2018-06-21T21:59:39.491Z",
"id": "555c1f7c5asdf7000167d87b"
},
"url_offset": {
"index": 36,
"type": "text"
},
"sg_message_id": "F5mwV1rESdyKFA_2bn1IEQ.filter0042p3las1-15933-5B2A68E8-36.0",
"useragent": "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)",
"email": "no.name@noname.com"
}, {
"sg_event_id": "fru_s2s1RtueuqBMNoIoTg",
"timestamp": 1529618255,
"url": "https://noname.com?utm_campaign=website&utm_source=sendgrid.com&utm_medium=email",
"ip": "192.168.1.1",
"event": "click",
"keen": {
"timestamp": "2018-06-21T21:57:35.000Z",
"created_at": "2018-06-21T21:58:20.374Z",
"id": "555c1f7c5asdf7000167d87b"
},
"url_offset": {
"index": 29,
"type": "text"
},
"sg_message_id": "F5mwV1rESdyKFA_2bn1IEQ.filter0042p3las1-15933-5B2A68E8-36.0",
"useragent": "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)",
"email": "no.name@noname.com"
}
]
}
您提供的 JSON 数据由一个具有单个 属性、result
的对象组成。 result
包含一个对象数组,每个对象代表一个具有字段->值属性的记录。
在您的函数中,您正在创建一个 row
数组并将整个 result
数组作为数组的单个元素推送。
在工作表中,一行由每个单元格一个元素的数组表示。
您需要处理 result
数组并将每个元素从具有 field->value 属性的对象转换为每个元素具有一个字段值的数组。
这是一个开始:
var rawdata = JSON.parse(json);
// Flatten each record.
for (var i = 0; i < rawdata.result.length; i++) {
rawdata.result[i] = flatten(rawdata.result[i]);
}
// Extract headers by scanning all results.
var headers = [];
for (var i = 0; i < rawdata.result.length; i ++) {
for (var field in rawdata.result[i]) {
if (!rawdata.result[i].hasOwnProperty(field)) continue;
if (headers.indexOf(field) > -1) continue;
headers.push(field);
}
}
headers.sort();
// Will contain an array of row arrays.
var data = [];
data.push(headers);
// Convert each result object into a row array and append to output.
for (var i = 0; i < rawdata.result.length; i++) {
var row = [];
for (var j = 0; j < headers.length; j++) {
if (!rawdata.result[i].hasOwnProperty(headers[j])) {
row.push("");
} else {
row.push(rawdata.result[i][headers[j]]);
}
}
data.push(row);
}
下面是 flatten()
的实现:
function flatten(obj, opt_prefix) {
if (typeof obj !== 'object' || obj === null) {
Logger.log(obj);
throw "Cannot flatten non-object";
}
var prefix = opt_prefix ? opt_prefix + '.' : '';
var result = {};
for (var k in obj) {
if (!obj.hasOwnProperty(k)) continue;
if (typeof obj[k] === 'object') {
var nested = flatten(obj[k], k);
for (var n in nested) {
if (!nested.hasOwnProperty(n)) continue;
result[prefix + n] = nested[n];
}
continue;
}
result[prefix + k] = obj[k];
}
return result;
}
此实现仅展平嵌套对象。如果存在嵌套数组,将导致执行失败。它适用于您的示例数据,因为不存在嵌套数组。
另请注意,在 Javascript 中,对象属性是无序的。如果你想对它们进行排序,你需要在你的代码中这样做,或者通过排序(例如,参见 headers.sort()
调用),如果字段名称已知或两者的组合,则预定义顺序。
如何解析这样的 JSON?这是要提取到 Google 电子表格中的 Keenio 提取 API 查询数据。
我尝试使用以下代码解析返回的 JSON,但不知道如何访问嵌套对象和数组。
function myFunction() {
var URL = "https://api.keen.io/3.0/projects/" +
PROJECT_KEY + "/queries/extraction?api_key=" +
API_KEY + "&event_collection=" +
EVT_COL + "&timezone=" +
TIMEZONE + "&latest=" +
LATEST + "&property_names.........."
var response = UrlFetchApp.fetch(URL);
var json = response.getContentText();
var rawdata = JSON.parse(response.getContentText());
Logger.log(rawdata.result);
var data = [];
data.push(rawdata.result);
SpreadsheetApp.getActiveSheet().appendRow(data);
}
上面我写的简单函数来解析这个JSON,但是我无法使用点表示法获取嵌套对象和数组。
我在使用著名的 IMPORTJSON 代码时观察到的另一件事是,每次出现时列的顺序都会打乱,所以我在返回数据上写的公式,用于导致参考错误。
{
"result": [
{
"sg_event_id": "92-OndRfTs6fZjNdHWzLBw",
"timestamp": 1529618395,
"url": "https://noname.com?utm_campaign=website&utm_source=sendgrid.com&utm_medium=email",
"ip": "192.168.1.1",
"event": "click",
"keen": {
"timestamp": "2018-06-21T21:59:55.000Z",
"created_at": "2018-06-21T22:00:28.532Z",
"id": "555c1f7c5asdf7000167d87b"
},
"url_offset": {
"index": 38,
"type": "text"
},
"sg_message_id": "F5mwV1rESdyKFA_2bn1IEQ.filter0042p3las1-15933-5B2A68E8-36.0",
"useragent": "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)",
"email": "no.name@noname.com"
}, {
"sg_event_id": "bjMlfsSfRyuXEVy8LndsYA",
"timestamp": 1529618349,
"url": "https://noname.com?utm_campaign=website&utm_source=sendgrid.com&utm_medium=email",
"ip": "192.168.1.1",
"event": "click",
"keen": {
"timestamp": "2018-06-21T21:59:09.000Z",
"created_at": "2018-06-21T21:59:39.491Z",
"id": "555c1f7c5asdf7000167d87b"
},
"url_offset": {
"index": 36,
"type": "text"
},
"sg_message_id": "F5mwV1rESdyKFA_2bn1IEQ.filter0042p3las1-15933-5B2A68E8-36.0",
"useragent": "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)",
"email": "no.name@noname.com"
}, {
"sg_event_id": "fru_s2s1RtueuqBMNoIoTg",
"timestamp": 1529618255,
"url": "https://noname.com?utm_campaign=website&utm_source=sendgrid.com&utm_medium=email",
"ip": "192.168.1.1",
"event": "click",
"keen": {
"timestamp": "2018-06-21T21:57:35.000Z",
"created_at": "2018-06-21T21:58:20.374Z",
"id": "555c1f7c5asdf7000167d87b"
},
"url_offset": {
"index": 29,
"type": "text"
},
"sg_message_id": "F5mwV1rESdyKFA_2bn1IEQ.filter0042p3las1-15933-5B2A68E8-36.0",
"useragent": "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)",
"email": "no.name@noname.com"
}
]
}
您提供的 JSON 数据由一个具有单个 属性、result
的对象组成。 result
包含一个对象数组,每个对象代表一个具有字段->值属性的记录。
在您的函数中,您正在创建一个 row
数组并将整个 result
数组作为数组的单个元素推送。
在工作表中,一行由每个单元格一个元素的数组表示。
您需要处理 result
数组并将每个元素从具有 field->value 属性的对象转换为每个元素具有一个字段值的数组。
这是一个开始:
var rawdata = JSON.parse(json);
// Flatten each record.
for (var i = 0; i < rawdata.result.length; i++) {
rawdata.result[i] = flatten(rawdata.result[i]);
}
// Extract headers by scanning all results.
var headers = [];
for (var i = 0; i < rawdata.result.length; i ++) {
for (var field in rawdata.result[i]) {
if (!rawdata.result[i].hasOwnProperty(field)) continue;
if (headers.indexOf(field) > -1) continue;
headers.push(field);
}
}
headers.sort();
// Will contain an array of row arrays.
var data = [];
data.push(headers);
// Convert each result object into a row array and append to output.
for (var i = 0; i < rawdata.result.length; i++) {
var row = [];
for (var j = 0; j < headers.length; j++) {
if (!rawdata.result[i].hasOwnProperty(headers[j])) {
row.push("");
} else {
row.push(rawdata.result[i][headers[j]]);
}
}
data.push(row);
}
下面是 flatten()
的实现:
function flatten(obj, opt_prefix) {
if (typeof obj !== 'object' || obj === null) {
Logger.log(obj);
throw "Cannot flatten non-object";
}
var prefix = opt_prefix ? opt_prefix + '.' : '';
var result = {};
for (var k in obj) {
if (!obj.hasOwnProperty(k)) continue;
if (typeof obj[k] === 'object') {
var nested = flatten(obj[k], k);
for (var n in nested) {
if (!nested.hasOwnProperty(n)) continue;
result[prefix + n] = nested[n];
}
continue;
}
result[prefix + k] = obj[k];
}
return result;
}
此实现仅展平嵌套对象。如果存在嵌套数组,将导致执行失败。它适用于您的示例数据,因为不存在嵌套数组。
另请注意,在 Javascript 中,对象属性是无序的。如果你想对它们进行排序,你需要在你的代码中这样做,或者通过排序(例如,参见 headers.sort()
调用),如果字段名称已知或两者的组合,则预定义顺序。