В Hive, как правильно использовать get_json_object для извлечения значения, когда в пути есть знак `$`

value
{"$screen_width":375,"$app_version":"2.5.0"}

Предположим, у меня есть таблица, показанная выше. Значение "2.5.0" это то, что я хочу Я пытаюсь использовать get_json_object но это не удается. Потому что путь "$app_version" включает в себя $ знак и Hive рассматривает его как знак корневого каталога.

Я пытаюсь несколькими способами кода, но все терпят неудачу и возвращаются NULL,

select get_json_object(value,"$.$app_version")
select get_json_object(value,"$.\\$app_version")
select get_json_object(value,"$.\$app_version")
select get_json_object(value,"$..app_version")

Любой продвинутый пользователь Hive знает, как это исправить?

Временно, я использую регулярное выражение, чтобы решить это.

select 
    regexp_extract(
        properties
        ,'\\"\\$os_version\\":\\"[\\d?]+\\.[\\d?]+\\.[\\d?]+\\"'
        ,0
    )
    ,properties
from opd.test_json_object

Тем не менее, мне любопытно, что нет никаких шансов использовать get_json_object Вот?

1 ответ

Не уверен, как получить значение напрямую $ подписать, но, как правило, вы должны рассмотреть lateral view с json_tuple (см. документ) вместо get_json_object, С точки зрения производительности это намного быстрее, и мне лично нравится тот факт, что столбцы json становятся "обычными" столбцами.

Для вашего примера я бы предложил следующее:

-- CTE to simulate a temporary table
with json as (
  select '{"$screen_width":375,"$app_version":"2.5.0"} ' as value
)
-- actual query
select *
from json 
lateral view 
  json_tuple(value, "$screen_width", "$app_version") lv as 
    screen_width, app_version;

Результат:

+------------------------------------------------+------------------+-----------------+
|                   json.value                   | lv.screen_width  | lv.app_version  |
+------------------------------------------------+------------------+-----------------+
| {"$screen_width":375,"$app_version":"2.5.0"}   | 375              | 2.5.0           |
+------------------------------------------------+------------------+-----------------+

Так что теперь вы можете просто использовать lv.app_version в вашем select заявление (вместо моего *), чтобы получить значение, которое вы ищете.

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