web-dev-qa-db-fra.com

Lecture de JSON avec Apache Spark - `corrupt_record`

J'ai un fichier json, nodes qui ressemble à ceci:

[{"toid":"osgb4000000031043205","point":[508180.748,195333.973],"index":1}
,{"toid":"osgb4000000031043206","point":[508163.122,195316.627],"index":2}
,{"toid":"osgb4000000031043207","point":[508172.075,195325.719],"index":3}
,{"toid":"osgb4000000031043208","point":[508513,196023],"index":4}]

Je suis capable de lire et de manipuler cet enregistrement avec Python.

J'essaie de lire ce fichier dans scala à travers le spark-Shell.

De ce tutorial , je peux voir qu’il est possible de lire json via sqlContext.read.json

val vfile = sqlContext.read.json("path/to/file/nodes.json")

Cependant, cela entraîne une erreur corrupt_record:

vfile: org.Apache.spark.sql.DataFrame = [_corrupt_record: string]

Quelqu'un peut-il nous éclairer sur cette erreur? Je peux lire et utiliser le fichier avec d'autres applications et je suis convaincu qu'il n'est pas corrompu et qu'il ressemble json.

11
LearningSlowly

Spark ne peut pas lire le tableau JSON dans un enregistrement de niveau supérieur, vous devez donc passer:

{"toid":"osgb4000000031043205","point":[508180.748,195333.973],"index":1} 
{"toid":"osgb4000000031043206","point":[508163.122,195316.627],"index":2} 
{"toid":"osgb4000000031043207","point":[508172.075,195325.719],"index":3} 
{"toid":"osgb4000000031043208","point":[508513,196023],"index":4}

Comme décrit dans le tutoriel vous faites référence à:

Commençons par charger un fichier JSON, où chaque ligne est un objet JSON

Le raisonnement est assez simple. Spark s'attend à ce que vous transmettiez un fichier contenant de nombreuses entités JSON afin de pouvoir répartir leur traitement (par entité, en gros). C'est pourquoi il s'attend à analyser une entité au niveau supérieur mais obtient un tableau, ce qui est impossible à mapper à un enregistrement car il n'y a pas de nom pour cette colonne. Fondamentalement (mais pas précisément), Spark voit votre tableau comme une ligne avec une colonne et ne parvient pas à trouver un nom pour cette colonne.

Pour plus de clarté, voici un formulaire de devis le document officiel

Notez que le fichier proposé comme fichier json n’est pas un fichier .__ typique. Fichier JSON. Chaque ligne doit contenir un identifiant valide distinct autonome Objet JSON. En conséquence, un fichier JSON multiligne standard sera le plus souvent échouer.

Ce format est souvent appelé _ JSONL . Fondamentalement, c'est une alternative au format CSV.

15
dk14

Pour lire le JSON multiligne en tant que DataFrame:

val spark = SparkSession.builder().getOrCreate()

val df = spark.read.json(spark.sparkContext.wholeTextFiles("file.json").values)

La lecture de gros fichiers de cette manière n’est pas recommandée, à partir de la documentation wholeTextFiles

Les fichiers de petite taille sont préférables, les fichiers de grande taille sont également autorisés mais peuvent entraîner de mauvaises performances.

9
Datageek

Comme Spark s'attend à ce que le "format de ligne JSON" ne soit pas un format JSON typique, nous pouvons dire à spark de lire le code JSON typique en spécifiant:

val df = spark.read.option("multiline", "true").json("<file>")
2
SandeepGodara

Je rencontre le même problème. J'ai utilisé sparkContext et sparkSql sur la même configuration:

val conf = new SparkConf()
  .setMaster("local[1]")
  .setAppName("Simple Application")


val sc = new SparkContext(conf)

val spark = SparkSession
  .builder()
  .config(conf)
  .getOrCreate()

Puis, en utilisant le contexte spark, j'ai lu le fichier JSON entier (JSON - chemin du fichier):

 val jsonRDD = sc.wholeTextFiles(JSON).map(x => x._2)

Vous pouvez créer un schéma pour les futures sélections, filtres ...

val schema = StructType( List(
  StructField("toid", StringType, nullable = true),
  StructField("point", ArrayType(DoubleType), nullable = true),
  StructField("index", DoubleType, nullable = true)
))

Créez un DataFrame en utilisant spark sql:

var df: DataFrame = spark.read.schema(schema).json(jsonRDD).toDF()

Pour tester, utilisez show et printSchema:

df.show()
df.printSchema()

sbt build file:

name := "spark-single"

version := "1.0"

scalaVersion := "2.11.7"

libraryDependencies += "org.Apache.spark" %% "spark-core" % "2.0.2"
libraryDependencies +="org.Apache.spark" %% "spark-sql" % "2.0.2"
0
Robert Gabriel