Сбор данных из массива JSON в таблицу ClickHouse

У меня есть необработанные данные JSON в таблице ClickHouse (на самом деле, netflow V9 из сборщика netflow), это выглядит так:

{"AgentID":"10.1.8.1",
       "Header":{"Version":9,"Count":2},
       "DataSets":[
            [{"I":2,"V":"231"},{"I":3,"V":"151"},{"I":8,"V":"109.195.122.130"}],
            [{"I":2,"V":"341"},{"I":3,"V":"221"},{"I":8,"V":"109.195.122.233"}]
       
       ]}'

Моя задача - преобразовать массивы DataSets в другую таблицу ClickHouse следующим образом:

I2     I3    I8
-----------------------------
231    151   109.195.122.130
341    221   109.195.122.233
...
 

person Ilya Varivchenko    schedule 09.02.2021    source источник


Ответы (1)


Для синтаксического анализа JSON рассмотрите возможность использования специализированных функций json:

SELECT
    toInt32(column_values[1]) AS I2,
    toInt32(column_values[2]) AS I3,
    column_values[3] AS I8
FROM 
(
    SELECT
        arrayJoin(JSONExtract(json, 'DataSets', 'Array(Array(Tuple(Int32, String)))')) AS row,
        arraySort(x -> (x.1), row) AS row_with_sorted_columns,
        arrayMap(x -> (x.2), row_with_sorted_columns) AS column_values
    FROM 
    (
        SELECT '{"AgentID":"10.1.8.1", "Header":{"Version":9,"Count":2}, "DataSets":[\n          [{"I":3,"V":"151"},{"I":8,"V":"109.195.122.130"},{"I":2,"V":"231"}],\n          [{"I":2,"V":"341"},{"I":3,"V":"221"},{"I":8,"V":"109.195.122.233"}]]}' AS json
    )
)


/*
┌─I2──┬─I3──┬─I8──────────────┐
│ 231 │ 151 │ 109.195.122.130 │
│ 341 │ 221 │ 109.195.122.233 │
└─────┴─────┴─────────────────┘
*/

(Чтобы узнать больше о синтаксическом анализе JSON, см. Как извлечь json из json в Clickhouse ?)


Вышеупомянутая реализация опирается на фиксированную структуру Datasets-array. Как я понял в реальном мире, эта структура имеет произвольную схему (https://www.iana.org/assignments/ipfix/ipfix.xhtml), например:

{
   "AgentID":"192.168.21.15",
   "Header":{},
   "DataSets":[
      [
         {"I":8, "V":"192.16.28.217"},
         {"I":12, "V":"180.10.210.240"},
         {"I":5, "V":2},
         {"I":4, "V":6},
         {"I":7, "V":443},
         {"I":6, "V":"0x10"}
      ]
   ]
}

Таким образом, возникает вопрос о таблице с произвольным количеством столбцов. ClickHouse не поддерживает эту функцию - посмотрите, как можно представить таблицу в этом случае https://stackoverflow.com/search?q=%5Bclickhouse%5D+pivot.

person vladimir    schedule 09.02.2021