Читайте многострочный JSON в Apache Spark
Я пытался использовать 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
}
Exeption:
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, чтобы сделать его oneliner, все работает нормально.
{"id": 1, "name": "Morty", "age": 21}
Итак, проблема в newline
.
UPD3
Я нашел в документах следующее предложение:
Обратите внимание, что файл, который предлагается в виде json файла, не является типичным файлом JSON. Каждая строка должна содержать отдельный автономный действительный объект JSON. Как следствие, обычный многострочный файл JSON чаще всего терпит неудачу.
Невозможно сохранить JSON в таком формате. Есть ли какое-либо обходное решение, чтобы избавиться от многослойной структуры JSON или преобразовать ее в oneliner?
Ответы
Ответ 1
Искры> = 2,2
Spark 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())
Ответ 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.