В 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
заявление (вместо моего *
), чтобы получить значение, которое вы ищете.