Разбор данных запроса API Keenio Extraction в электронную таблицу Google

Как мне разобрать JSON, как это? Это данные запроса API-интерфейса Keenio для извлечения в таблицу Google.

Я попытался использовать следующий код для анализа возвращенного 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"
    }
  ]
}

1 ответ

Решение

Предоставленные вами данные JSON состоят из объекта с одним свойством, result, result содержит массив объектов, каждый из которых представляет запись со свойствами field->value.

В вашей функции вы создаете 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() call), предварительно определяя порядок, если известны имена полей или их комбинация.

Другие вопросы по тегам