2017-07-15 4 views
0

Je suis nouveau à travailler avec des données json sur la ruche. Je travaille sur une application spark qui récupère des données json et les stocke dans des tables de ruche. J'ai un JSON comme ceci:java.lang.ClassCastException: org.apache.hadoop.hive.ql.io.orc.OrcStruct ne peut pas être converti en org.apache.hadoop.io.Text. Erreur avec json serde

Json of Jsons

qui ressemble à ceci lorsqu'elle est dépliée:

hierarchy

Je suis capable de lire le JSON dans une trame de données et l'enregistrer dans un emplacement sur HDFS . Mais obtenir ruche pour être capable de lire les données est la partie difficile.

Après que j'ai cherché en ligne par exemple, j'ai essayé de le faire:

utilisant le STRUCT pour tous les champs de JSON et accéder aux éléments à l'aide column.element.

Par exemple:

web_app_security sera le nom d'une colonne (de type STRUCT) à l'intérieur de la table et les autres jsons en elle comme config_web_cms_authentication, web_threat_intel_alert_external sera également Structs (avec rating et rating_numeric comme les champs) .

J'ai essayé de créer la table avec json serde. voici ma définition de table:

CREATE EXTERNAL TABLE jsons (
web_app_security struct<config_web_cms_authentication: struct<rating: string, rating_numeric: float>, web_threat_intel_alert_external: struct<rating: string, rating_numeric: float>, web_http_security_headers: struct<rating: string, rating_numeric: float>, rating: string, rating_numeric: float>, 
dns_security struct<domain_hijacking_protection: struct<rating: string, rating_numeric: float>, rating: string, rating_numeric: float, dns_hosting_providers: struct<rating:string, rating_numeric: float>>, 
email_security struct<rating: string, email_encryption_enabled: struct<rating: string, rating_numeric: float>, rating_numeric: float, email_hosting_providers: struct<rating: string, rating_numeric: float>, email_authentication: struct<rating: string, rating_numeric: float>>, 
threat_intell struct<rating: string, threat_intel_alert_internal_3: struct<rating: string, rating_numeric: float>, threat_intel_alert_internal_1: struct<rating: string, rating_numeric: float>, rating_numeric: float, threat_intel_alert_internal_12: struct<rating: string, rating_numeric: float>, threat_intel_alert_internal_6: struct<rating: string, rating_numeric: float>>, 
data_loss struct<data_loss_6: struct<rating: string, rating_numeric: float>, rating: string, data_loss_36plus: struct<rating: string, rating_numeric: float>, rating_numeric: float, data_loss_36: struct<rating: string, rating_numeric: float>, data_loss_12: struct<rating: string, rating_numeric: float>, data_loss_24: struct<rating: string, rating_numeric: float>>, 
system_hosting struct<host_hosting_providers: struct<rating: string, rating_numeric: float>, hosting_countries: struct<rating: string, rating_numeric: float>, rating: string, rating_numeric: float>, 
defensibility struct<attack_surface_web_ip: struct<rating: string, rating_numeric: float>, shared_hosting: struct<rating: string, rating_numeric: float>, defensibility_hosting_providers: struct<rating: string, rating_numeric: float>, rating: string, rating_numeric: float, attack_surface_web_hostname: struct<rating: string, rating_numeric: float>>, 
software_patching struct<patching_web_cms: struct<rating: string, rating_numeric: float>, rating: string, patching_web_server: struct<rating: string, rating_numeric: float>, patching_vuln_open_ssl: struct<rating: string, rating_numeric: float>, patching_app_server: struct<rating: string, rating_numeric: float>, rating_numeric: float>, 
governance struct<governance_customer_base: struct<rating: string, rating_numeric: float>, governance_security_certifications: struct<rating: string, rating_numeric: float>, governance_regulatory_requirements: struct<rating: string, rating_numeric: float>, rating: string, rating_numeric: float> 
)ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe' 
STORED AS orc 
LOCATION 'hdfs://nameservice1/data/gis/final/rr_current_analysis' 

J'ai essayé d'analyser les lignes avec le json serde. Après que je l'ai sauvé des données à la table, je reçois l'erreur suivante lorsque je tente de l'interroger:

Error: java.io.IOException: java.lang.ClassCastException: org.apache.hadoop.hive.ql.io.orc.OrcStruct cannot be cast to org.apache.hadoop.io.Text (state=,code=0) 

Je ne sais pas si je suis en train de faire ce la bonne façon.

Je suis ouvert à toute autre manière de stocker les données dans la table. Toute aide serait appréciée. Je vous remercie.

Répondre

1

C'est parce que vous mélangez ORC en tant que stockage (STORED AS orc) et JSON comme SerDe (ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe') par défaut de la SIO remplaçant OrcSerde de SerDe, mais pas d'entrée (OrcInputFormat) et de sortie (OrcOutputFormat) formats.

Vous devez utiliser le stockage ORC sans outrepasser son SerDe par défaut. Dans ce cas, assurez-vous que votre application Spark écrit dans les tables ORC, et non dans JSON. Ou, si vous souhaitez que les données soient stockées dans JSON, utilisez JsonSerDe avec un fichier texte brut comme stockage (STORED AS TEXTFILE).


Ruche Guide du développeur a des explications sur la façon dont le travail SerDe et stockage - https://cwiki.apache.org/confluence/display/Hive/DeveloperGuide#DeveloperGuide-HiveSerDe

+0

Merci pour la réponse. Je marche pour sauver mon dataframe sous forme de fichier texte en utilisant 'df.rdd.saveAsTextFile (" Path ")' mais j'obtiens son erreur 'org.apache.hadoop.mapred.FileAlreadyExistsException: Le répertoire de sortie existe déjà' Je ne suis pas sûr de savoir pourquoi essaie de créer un nouveau répertoire pour chaque dataframe au lieu de créer un nouveau fichier dans le chemin donné.Existe-t-il un meilleur moyen de sauvegarder le fichier de données sous forme de fichier texte? ou Y a-t-il un moyen de sauvegarder la trame de données en tant que csv et de donner une définition de table appropriée pour lire les fichiers csv et utiliser le fichier json serde ?? @Sergey Khudyakov –

+0

@HemanthAnnavarapu à la place de 'df.write' et surtout' df.write.mode (SaveMode) '. Je ne sais pas pourquoi vous faites référence aux fichiers CSV maintenant, mais je vous recommande fortement de lire le Guide du développeur Hive (lien dans la réponse) en premier et la documentation de l'API Spark DataFrame. La "meilleure façon" dépend vraiment de ce que vous voulez accomplir, du type de tables que vous voulez avoir dans Hive, etc. –

+0

J'essaie maintenant avec csv parce que j'ai cherché à sauvegarder une dataframe sous forme de texte et dans la plupart des cas des exemples auxquels ils font référence en utilisant 'DF.write.format (" org.databricks.spark.csv "). save (" path ")'. Puisque 'Df.saveAsTextFile' ne fonctionne pas, j'essaye avec csv. Est-ce que je peux toujours utiliser le fichier 'serde' sur les fichiers' csv'? Ou est-il possible pour moi de surcharger 'format d'entrée' en utilisant le format' orc'? @Sergey Khudyakov –