java.NullPointException в методе DataFrame.show () в Spark - scala

РЕДАКТИРОВАТЬ: извините за качество предыдущего вопроса, я надеюсь, что этот будет более ясным: с помощью приложения Spark я загружаю весь каталог следующих файлов JSON:

    {
        "type": "some_type",
        "payload": {
            "data1": {
                "id": "1"           
            },
            "data2": {
                "id": "1",

            },
            "data3": {
                "id": "1"
            },
            "dataset1": [{
                "data11": {
                    "id": "1",
                },
                "data12": {
                    "id": "1",
                }
            }],
            "masterdata": {
                "md1": [{
                    "id": "1"
                },
                {
                    "id": "2"
                },
                {
                    "id": "3"
                }],
                "md2": [{
                    "id": "1",
                },
                {
                    "id": "2",
                },
                {
                    "id": "3",
                }]
            }
        }
    }

в DataFrame и сохраните как временную таблицу, чтобы использовать ее позже. В этом Json всегда присутствуют поля из узла «payload», но подузлы в «masterdata» необязательны. Следующим шагом является создание нескольких DataFrames для каждого подузла Json следующим образом: DataFrame data1 содержит данные узла «data1» из всех файлов и выглядит как обычная таблица со столбцом «id». После первой части обработки мое состояние Spark выглядит следующим образом: DataFrames: data1 (id), data2 (id), data3 (id), data11 (id), data12 (id), md1 (id), md2 (id)

Здесь возникает проблема - если один из файлов JSON в каталоге не содержит узла md2, я не могу запустить ни show(), ни collect() на фрейме данных «md2» из-за исключения NullPointException. Я бы понял, если во всех файлах отсутствует узел "md2", поэтому он не может создать md2 DataFrame, но в этом случае я ожидаю, что md2 DataFrame просто не будет иметь данных из файла json, который не имеет узла md2, но содержит все остальные.

Технические детали: для чтения данных из вложенного узла я использую rdd.map & rdd.flatmap, затем конвертирую его в DataFrame с пользовательскими именами столбцов

Если я запускаю приложение, когда все файлы в каталоге содержат все узлы, все работает, но если один файл отсутствует, узел md2 Приложение не работает при .show () или .collect ()

Кстати, если узел существует, но он пуст, все работает нормально.

Есть ли способ заставить Spark поддерживать дополнительные узлы Json или обрабатывать отсутствующие узлы в rdd.map и flatmap?

Надеюсь, это более ясно, чем в предыдущем вопросе

По запросу @Beryllium вот операции rdd, которые я использую для получения md2 DataFrame

    val jsonData = hiveContext.sql("SELECT `payload`.masterdata.md2 FROM jsonData")
    val data = jsonData.rdd.flatMap(row => row.getSeq[Row](0)).map(row => (
    row.getString(row.fieldIndex("id"))
    )).distinct
    val dataDF = data.toDF("id")    

person Silverrose    schedule 27.11.2015    source источник
comment
Возможный дубликат Что такое нулевой указатель Исключение, и как его исправить?   -  person Petter Friberg    schedule 27.11.2015
comment
@PetterFriberg при всем уважении, это не потому, что на нем есть NPE, что это дубликат, в данном случае это не так.   -  person eliasah    schedule 27.11.2015
comment
@Silverrose вам необходимо предоставить MCVE, чтобы мы могли помочь!   -  person eliasah    schedule 27.11.2015
comment
@eliasah Извините, но поскольку текущий вопрос опубликован, я думаю, что это лучший ответ, который можно дать.   -  person Petter Friberg    schedule 27.11.2015
comment
@PetterFriberg не о чем сожалеть. Полностью согласен по поводу некачественной мысли вопроса!   -  person eliasah    schedule 27.11.2015
comment
@all Я постараюсь подготовить что-то более читабельное :)   -  person Silverrose    schedule 27.11.2015
comment
Все еще недостаточно; добавьте rdd.map/flatMaps и преобразование в DF - невозможно воспроизвести вашу проблему с использованием простого sqlContext.read.json.   -  person Beryllium    schedule 27.11.2015


Ответы (1)


Быстрая починка

Попробуйте вставить filter() вот так:

sqlContext.sql("SELECT payload.masterdata.md2 FROM jsonData")
  .rdd
  .filter(_.getSeq[Row](0) != null)
  .flatMap(row => row.getSeq[Row](0))
  .map(row => (row.getString(row.fieldIndex("id"))))
  .distinct
  .toDF("id")
  .show()

Использование explode ()

Это удалит нулевые значения как можно скорее: так должно быть быстрее (по крайней мере, короче):

sqlContext
  .sql("select t.a.id from (SELECT explode(payload.masterdata.md2) as a FROM jsonData) t")
  • explode() взрывается null.
  • Затем подзапрос извлекает только идентификатор

Еще проще: сначала извлечь ID, а затем explode():

sqlContext.sql("SELECT explode(payload.masterdata.md2.id) FROM jsonData").show()
person Beryllium    schedule 27.11.2015
comment
@Silverrose Это просто быстрый взлом; подскажите пожалуйста, если вернет ожидаемый результат - наверное есть способы получше. - person Beryllium; 27.11.2015
comment
@up Спасибо, работа выполнена. Я думал, что он автоматически проигнорирует пустые значения, поскольку схема была готова для дополнительных узлов. Мне все еще неясно, почему исключение выбрасывается в .show (), а не при обработке? Это позволяет мне создать DataFrame и использовать его позже, но выдает исключение, как только я пытаюсь отобразить этот DF или другой на основе этого. - person Silverrose; 27.11.2015
comment
Схема в порядке - карта не работает. А поскольку RDD оценивается лениво, вы видите ошибку в show(), потому что именно там результат в конечном итоге материализуется. - person Beryllium; 27.11.2015
comment
Я буду помнить о решении Explode, когда буду бороться с проблемами производительности, пока rdd.map в порядке. Большое спасибо! - person Silverrose; 27.11.2015