2016-04-06 2 views
2

Возможно ли использовать элемент Option[_] в классе case, используемом с API Dataset API? например. Option[Int]Как создать кодировщик для конструктора типа Option, например. Опция [Int]?

Я попытался найти пример, но не смог найти его. Возможно, это можно сделать с помощью настраиваемого кодировщика (сопоставление?), Но пока я не смог найти пример.

Это может быть достигнуто с использованием библиотеки Frameless: https://github.com/adelbertc/frameless, но должен быть простой способ сделать это с помощью базовых библиотек Spark.

Update

Я использую: "org.apache.spark" %% "spark-core" % "1.6.1"

И получаю следующее сообщение об ошибке при попытке использовать один вариант [Int]:

Невозможно найти кодер типа, хранящуюся в Dataset. Примитивные типы (Int, String и т.д.) и типов продукции (тематические классы) поддерживаются импорта sqlContext.implicits._ Поддержка сериализации других типов будут добавлены в будущих версиях

обновление Решение

Поскольку я был прототипом, я просто объявлял класс case внутри функции перед преобразованием в набор данных (в моем случае внутри object Main {).

Типы опций работали нормально, когда я переместил класс case за пределы основной функции.

ответ

8

Мы определяем имплициты для подмножества типов, поддерживаемых in SQLImplicits. Вероятно, следует рассмотреть вопрос о добавлении Option[T] для общего T, поскольку внутренняя инфраструктура действительно понимает Option. Вы можете обойти это, создав case class, используя Tuple или constructing the required implicit yourself (хотя это и внутренний API, поэтому он может ломаться в будущих выпусках).

implicit def optionalInt: org.apache.spark.sql.Encoder[Option[Int]] = org.apache.spark.sql.catalyst.encoders.ExpressionEncoder() 

val ds = Seq(Some(1), None).toDS() 
+0

Я нашел ошибку, которую я делал, кажется, что scala рассматривает объявление класса case внутри функции и вне ее по-разному. Объявление класса case за пределами Main разрешало функции 'as [_]' работать без каких-либо дополнительных неявных. Я попытался использовать подразумеваемое вами упоминание, но я не мог заставить его работать (для случая, когда класс case определен внутри функции, например Main). Мой источник данных - это база данных MS SQL Server. –

+0

По какой-то причине кодировка типа Timestamp работает, но GregorianCalendar этого не делает, оба не указаны в файле, указанном в комментарии AlexeyRomanov –

2

«Поддержка будущих сериализации будет добавлена ​​в будущих выпусках». Пользовательские кодеры пока не поддерживаются, хотя, очевидно, это запланировано. Вы могли бы попытаться реализовать свой признак самостоятельно, но, безусловно, нет официальных примеров.

Один из вариантов заключается в использовании члена Seq[Int] и обеспечения его наличия только одного значения.

+2

Вы можете принять этот ответ и мой комментарий выше и объединить их - класс case под названием «НеобязательныйInt», обернутый вокруг 'Seq [Int]'. Затем вы можете реализовать 'isDefined' и' isEmpty' и 'get' и даже' getOrElse' в классе case. –

+1

@DavidGriffin: Не могли бы вы добавить ответ для этого, пожалуйста? Моя Скала немного ржавая. Я постараюсь реализовать его тем временем. –

+0

@ Alexey Romanov: Кажется, что 'Seq [Int]' рассматривается как неподдерживаемый тип, поэтому он не будет работать. –

Смежные вопросы