/ / Читання багаторядкового JSON в Apache Spark - json, apache-spark, apache-spark-sql

Читайте багаторядковий JSON в Apache Spark - json, apache-spark, apache-spark-sql

Я намагався використовувати файл JSON як невелику БД. Після створення таблиці шаблонів на DataFrame я запитував її в SQL і отримав виняток. Ось мій код:

val df = sqlCtx.read.json("/path/to/user.json")
df.registerTempTable("user_tt")

val info = sqlCtx.sql("SELECT name FROM user_tt")
info.show()

df.printSchema() результат:

root
|-- _corrupt_record: string (nullable = true)

Мій файл JSON:

{
"id": 1,
"name": "Morty",
"age": 21
}

Виняток:

Exception in thread "main" org.apache.spark.sql.AnalysisException: cannot resolve "name" given input columns: [_corrupt_record];

Як я можу це виправити?

UPD

_corrupt_record є

+--------------------+
|     _corrupt_record|
+--------------------+
|                   {|
|            "id": 1,|
|    "name": "Morty",|
|           "age": 21|
|                   }|
+--------------------+

UPD2

Це дивно, але коли я переписую свій JSON, щоб зробити його однолінійним, все працює нормально.

{"id": 1, "name": "Morty", "age": 21}

Отже, проблема в newline.

UPD3

Я знайшов у документах наступне речення:

Зверніть увагу, що файл, який пропонується як файл jsonне є типовим файлом JSON. Кожен рядок повинен містити окремий, автономний дійсний об'єкт JSON. Як наслідок, звичайний багаторядковий файл JSON найчастіше виходить з ладу.

Зберігати JSON у такому форматі не зручно. Чи існує якийсь обхідний спосіб, щоб позбутися багаторядкової структури JSON або перетворити її в oneliner?

Відповіді:

21 для відповіді № 1

Іскра> = 2.2

Введено Spark 2.2 wholeFile multiLine варіант, який можна використовувати для завантаження файлів JSON (а не JSONL):

spark.read
.option("multiLine", true).option("mode", "PERMISSIVE")
.json("/path/to/user.json")

Побачити:

  • ІСКРА-18352 - Розбір звичайних багаторядкових файлів JSON (не тільки рядків JSON).
  • ІСКРА-20980 - Перейменуйте опцію wholeFile до multiLine для JSON та CSV.

Іскра <2.2

Ну, використання форматованих даних JSONL може бутинезручно, але це я заперечую, що справа не в API, а в самому форматі. JSON просто не призначений для паралельної обробки в розподілених системах.

Він не надає схеми і не робить деякихдуже конкретні припущення щодо форматування та форми майже неможливо правильно визначити документи вищого рівня. Можливо, це найгірший з можливих форматів, який можна використовувати в таких системах, як Apache Spark. Також досить складно і, як правило, непрактично писати дійсний JSON у розподілених системах.

При цьому, якщо окремі файли є дійсними документами JSON (або один документ, або масив документів), ви завжди можете спробувати wholeTextFiles:

spark.read.json(sc.wholeTextFiles("/path/to/user.json").values())

3 для відповіді № 2

Просто для того, щоб додати відповідь до нуля 323, опцію в Spark 2.2+ читати багаторядковий JSON було перейменовано на multiLine (див. документацію Spark тут)

Тому правильний синтаксис:

spark.read
.option("multiLine", true).option("mode", "PERMISSIVE")
.json("/path/to/user.json")

Це сталося в https://issues.apache.org/jira/browse/SPARK-20980.