Как запросить значение с помощью get_json_object()

#json #pyspark #hive

Вопрос:

Мне нужно извлечь значение атрибута, в котором пространство имен является ГЛОБАЛЬНЫМ, в следующем формате json, например, в этом примере мне нужно извлечь «123456».

 [{  "namespace": "GLOBALID",  "key": "ID",  "value": "123456"  },  {  "namespace": "RPS",  "key": "ID",  "value": "12xt12"  } ]  

Однако, когда я использую select get_json_object(json_column, '$.GLOBALID.value') , он не извлекает значение (отредактировано)

Ответ №1:

Для pyspark создайте фрейм данных и фильтр.

 json = [  {  "namespace": "GLOBALID",  "key": "ID",  "value": "123456"  },  {  "namespace": "RPS",  "key": "ID",  "value": "12xt12"  } ]  df = spark.createDataFrame(json) df.show()  #  --- --------- ------  # |key|namespace| value| #  --- --------- ------  # | ID| GLOBALID|123456| # | ID| RPS|12xt12| #  --- --------- ------   
 df.filter("namespace = 'GLOBALID'").select('value').rdd.map(lambda x: x[0]).collect() # ['123456']  

Комментарии:

1. Я не могу использовать код python или фрейм данных в инструментах, которые я использую для ETL, разрешена только функция spark

Ответ №2:

Вам нужно будет проанализировать json строку как JSON значение, а затем применить фильтрацию. Это необходимо, так как Spark не позволяет фильтровать выражения в JSONPath .

  from pyspark.sql import functions as F from pyspark.sql.types import ArrayType, StringType, StructType, StructField  df = spark.createDataFrame([('[{"namespace":"GLOBALID","key":"ID","value":"123456"},{"namespace":"RPS","key":"ID","value":"12xt12"}]', ), ], ("json_column", ))   json_schema = ArrayType(StructType([StructField('namespace', StringType(),),   StructField('value', StringType(),)]))  df.select(F.explode(F.from_json("json_column", json_schema)).alias("json"))  .filter(F.col("json")["namespace"] == "GLOBALID")  .select("json.value")  .show()  

Выход

  ------  | value|  ------  |123456|  ------   

Комментарии:

1. Я не могу использовать код python или фрейм данных в инструментах, которые я использую для ETL, разрешена только функция spark

2. F.from_json и filter все это функции spark. Вы хотите сказать, что вы JSON как строка как есть?