парсинг json значение ключа в снежинке с ключом, содержащим точки - PullRequest
1 голос
/ 07 февраля 2020
{
  "deviceLocale": "en_US",
  "deviceSerialNumber": "xxxxxxxxxx",
  "eventSource": "abc",
  "ext.user.browser": "Mobile Safari",
  "ext.user.browser.version": "1.0.4",
  "ext.user.device.family": "iPhone", 
  "ext.user.os": "iOS",
  "ext.user.os.version": "1.3.0",
  "Timestamp": 158007896874 }

Это образец json, который у меня есть ..

Разбор в снежинке

```
select distinct
eve_id,
json_payload:ext.useragent.device.family::varchar as type,
json_payload:ext.useragent.os::varchar as osname,
json_payload:ext.useragent.os.version::varchar as os 
from XYZ table, lateral flatten (input => json_payload)
```

Но все эти три поля дают значения NULL, и я вижу данные в формате json. Так что я думаю, что разбор не является правильным. Я знаю в снежинке при разборе, если мы используем точку или: тогда это относится к вложенному ключу. Но в моем случае у меня есть простой json без вложенных ключей.

Есть идеи?

1 Ответ

1 голос
/ 07 февраля 2020

во-первых, вы можете поместить имя в двойные кавычки, например, так:

SELECT parse_json('{
        "deviceLocale": "en_US",
        "deviceSerialNumber": "xxxxxxxxxx",
        "eventSource": "abc",
        "ext.user.browser": "Mobile Safari",
        "ext.user.browser.version": "1.0.4",
        "ext.user.device.family": "iPhone", 
        "ext.user.os": "iOS",
        "ext.user.os.version": "1.3.0",
        "Timestamp": 158007896874 }') AS json_payload,
    json_payload:"ext.user.device.family"::varchar as type,
    json_payload:"ext.user.os"::varchar as osname,
    json_payload:"ext.user.os.version"::varchar as os;

дает:

JSON_PAYLOAD    TYPE    OSNAME  OS
{    "Timestamp": 158007896874,    "deviceLocale": "en_US",    "deviceSerialNumber": "xxxxxxxxxx",    "eventSource": "abc",    "ext.user.browser": "Mobile Safari",    "ext.user.browser.version": "1.0.4",    "ext.user.device.family": "iPhone",    "ext.user.os": "iOS",    "ext.user.os.version": "1.3.0"  }    iPhone  iOS 1.3.0

ИЛИ вы можете использовать формат [''], например json_payload['ext.user.os.version']::varchar as os, который разрешите избегать двойных кавычек (в случае, если вы хотите избежать этого).

При доступе к SQL у вас есть json_payload:ext.useragent.device.family::varchar, а в разделе useragent только user в вашем JSON. Так что это доставит вам неприятности.

Также в вашем примере вы используете LATERAL FLATTEN, но спрашиваете, как получить доступ к сплющенным элементам объекта, который вы сплющиваете. Так что сглаживать не нужно. Но если вы хотите получить флэт, то вы получите по строке для каждого элемента верхнего уровня, после чего вы захотите отфильтровать key .. но я подозреваю, что это не то, что вы пытаетесь сделать. Но если вам нужна хорошая псевдоним, чтобы показать намерение.

WITH jp AS (
    SELECT parse_json('{
      "deviceLocale": "en_US",
      "deviceSerialNumber": "xxxxxxxxxx",
      "eventSource": "abc",
      "ext.user.browser": "Mobile Safari",
      "ext.user.browser.version": "1.0.4",
      "ext.user.device.family": "iPhone", 
      "ext.user.os": "iOS",
      "ext.user.os.version": "1.3.0",
      "Timestamp": 158007896874 }') AS json_payload
)
SELECT 
    f.key,
    f.path,
    f.value
FROM jp, LATERAL FLATTEN (input => json_payload) f;

дает:

KEY PATH    VALUE
Timestamp   Timestamp   158007896874
deviceLocale    deviceLocale    "en_US"
deviceSerialNumber  deviceSerialNumber  "xxxxxxxxxx"
eventSource eventSource "abc"
ext.user.browser    ['ext.user.browser']    "Mobile Safari"
ext.user.browser.version    ['ext.user.browser.version']    "1.0.4"
ext.user.device.family  ['ext.user.device.family']  "iPhone"
ext.user.os ['ext.user.os'] "iOS"
ext.user.os.version ['ext.user.os.version'] "1.3.0"
...