Чтение файла Json с помощью Apache Spark

Я пытаюсь прочитать файл Json, используя Spark v2.0.0. В случае простых данных код работает очень хорошо. В случае немного сложных данных, когда я печатаю df.show(), данные отображаются неправильно.

вот мой код:

SparkSession session = SparkSession.builder().master("local").appName("jsonreader").getOrCreate();
Dataset<Row> list = session.read().json("/Users/hadoop/Desktop/sample.json");
list.show();

Вот мой образец данных:

{
    "glossary": {
        "title": "example glossary",
        "GlossDiv": {
            "title": "S",
            "GlossList": {
                "GlossEntry": {
                    "ID": "SGML",
                    "SortAs": "SGML",
                    "GlossTerm": "Standard Generalized Markup Language",
                    "Acronym": "SGML",
                    "Abbrev": "ISO 8879:1986",
                    "GlossDef": {
                        "para": "A meta-markup language, used to create markup languages such as DocBook.",
                        "GlossSeeAlso": ["GML", "XML"]
                    },
                    "GlossSee": "markup"
                }
            }
        }
    }
}

И мой вывод похож на:

+--------------------+
|     _corrupt_record|
+--------------------+
|                   {|
|       "glossary": {|
|        "title": ...|
|           "GlossDiv": {|
|            "titl...|
|               "GlossList": {|
|                "...|
|                 ...|
|                   "SortAs": "S...|
|                   "GlossTerm":...|
|                   "Acronym": "...|
|                   "Abbrev": "I...|
|                   "GlossDef": {|
|                 ...|
|                       "GlossSeeAl...|
|                 ...|
|                   "GlossSee": ...|
|                   }|
|                   }|
|                   }|
+--------------------+
only showing top 20 rows

person user6325753    schedule 24.10.2016    source источник


Ответы (5)


Вам нужно будет отформатировать JSON в одну строку, если вам нужно прочитать этот JSON. Это многострочный JSON, поэтому он не читается и не загружается должным образом (One Object one Row )

Цитирование JSON API:

Загружает файл JSON (один объект в строке) и возвращает результат в виде кадра данных.

{"glossary":{"title":"example glossary","GlossDiv":{"title":"S","GlossList":{"GlossEntry":{"ID":"SGML","SortAs":"SGML","GlossTerm":"Standard Generalized Markup Language","Acronym":"SGML","Abbrev":"ISO 8879:1986","GlossDef":{"para":"A meta-markup language, used to create markup languages such as DocBook.","GlossSeeAlso":["GML","XML"]},"GlossSee":"markup"}}}}}

Я только что попробовал это в оболочке, он должен работать и из кода таким же образом (у меня была такая же ошибка поврежденной записи, когда я читал многострочный JSON)

scala> val df = spark.read.json("C:/DevelopmentTools/data.json")
df: org.apache.spark.sql.DataFrame = [glossary: struct<GlossDiv: struct<GlossList: struct<GlossEntry: struct<Abbrev: string, Acronym: string ... 5 more fields>>, title: string>, title: string>]

scala>

Редактирует:

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

scala> df.select(df("glossary.GlossDiv.GlossList.GlossEntry.GlossTerm")).show()
+--------------------+
|           GlossTerm|
+--------------------+
|Standard Generali...|
+--------------------+


scala>

Вы также должны быть в состоянии сделать это из своего кода.

person Ramachandran.A.G    schedule 24.10.2016
comment
Спасибо за ваш ответ.. когда я попытался, я получил это в качестве вывода. +------+ | глоссарий| +--------------------+ |[[[[ISO 8879:1986...| +--------------------+ - person user6325753; 24.10.2016
comment
Это ожидаемо. Добавлен образец действия, чтобы показать оценку/обработку - person Ramachandran.A.G; 24.10.2016

Просто убедитесь, что ваш json находится в одной строке, которую вы читаете вложенный json, поэтому, если вы уже сделали это, вы успешно загрузили json, вы показываете его неправильно, его вложенный json, поэтому вы не можете напрямую показать, например, если вы хотите данные заголовка GlossDiv вы можете показать это следующим образом

SparkSession session = SparkSession.builder().master("local").appName("jsonreader").getOrCreate();
Dataset<Row> list = session.read().json("/Users/hadoop/Desktop/sample.json");
list.select("glossary.GlossDiv.title") .show
person Sandeep Purohit    schedule 24.10.2016

Пытаться:

session.read().json(session.sparkContext.wholeTextFiles("..."));
person Community    schedule 24.10.2016

Эта ветка немного устарела, я хочу просто уточнить, что предложил @user6022341. В итоге я использовал его в одном из своих проектов:

Для обработки многострочного json-файла преобразование fullTextFiles(String path) является единственным решением в spark, если файл представляет собой один большой json-объект. Это преобразование загрузит все содержимое файла в виде строки. Итак, если в каталоге hdfs://a-hdfs-path у вас есть два файла, а именно: part-00000 и part-00001. Вызов sparkContext.wholeTextFiles("hdfs://a-hdfs-path") приведет к тому, что Spark вернет JavaPairRDD с ключом в качестве имени файла и значением в качестве содержимого файла. Это может быть не лучшим решением и может снизить производительность для больших файлов.

Но если в многострочном файле json было несколько объектов json, разделенных на несколько строк, вы, вероятно, могли бы использовать hadoop.Configuration, показан пример кода здесь. Я не проверял это на себе.

If you had to read a multiline csv file, you could do this with Spark 2.2

spark.read.csv(file, multiLine=True)

https://issues.apache.org/jira/browse/SPARK-19610

https://issues.apache.org/jira/browse/SPARK-20980

Надеюсь, это поможет другим людям, которые ищут аналогичную информацию.

person skvyas    schedule 25.08.2017

Другой способ чтения файла JSON с использованием Java в Spark аналогичен упомянутому выше:

SparkSession spark = SparkSession.builder().appName("ProcessJSONData")
                        .master("local").getOrCreate();

String path = "C:/XX/XX/myData.json";

// Encoders are created for Java bean class
Encoder<FruitJson> fruitEncoder = Encoders.bean(FruitJson.class);

Dataset<FruitJson> fruitDS = spark.read().json(path).as(fruitEncoder);

fruitDS.show();
person RPaul    schedule 06.09.2018