/ / Прочетете многоредови JSON в Apache Spark - json, apache-искра, apache-искра-sql

Прочетете многоредови JSON в Apache Spark - json, apache-искра, apache-искра-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}

Така че проблемът е в a newline.

UPD3

Намерих в документи следващото изречение:

Обърнете внимание, че файлът, който се предлага като json файлне е типичен JSON файл. Всеки ред трябва да съдържа отделен, самостоятелен валиден JSON обект. В резултат на това редовен многоредов JSON файл най-често ще се провали.

Не е удобно да поддържате JSON в такъв формат. Има ли някакво решение, за да се отървете от многопластовата структура на JSON или да го преобразувате в oneliner?

Отговори:

21 за отговор № 1

Искри> = 2.2

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

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

Виж:

  • SPARK-18352 - Разбор на нормални многоредови JSON файлове (не само JSON линии).
  • SPARK-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

Само за да добавите отговора на zero323, опцията в 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.