Кодер для наборов данных типа Spark
Я хотел бы написать кодировщик для Row типа в DataSet для операции с картой, которую я делаю. По сути, я не понимаю, как писать кодировщики.
Ниже приведен пример операции с картой:
In the example below, instead of returning Dataset<String>, I would like to return Dataset<Row>
Dataset<String> output = dataset1.flatMap(new FlatMapFunction<Row, String>() {
@Override
public Iterator<String> call(Row row) throws Exception {
ArrayList<String> obj = //some map operation
return obj.iterator();
}
},Encoders.STRING());
Я понимаю, что вместо строки Encoder нужно записать следующим образом:
Encoder<Row> encoder = new Encoder<Row>() {
@Override
public StructType schema() {
return join.schema();
//return null;
}
@Override
public ClassTag<Row> clsTag() {
return null;
}
};
Однако, я не понимаю clsTag() в кодере, и я пытаюсь найти пример выполнения, который может демонстрировать нечто подобное (например, кодер для типа строки)
Изменить - это не копия упомянутого вопроса: Ошибка кодирования при попытке сопоставить строку dataframe с обновленной строкой, поскольку в ответе говорится об использовании Spark 1.x в Spark 2.x(я этого не делаю), также я ищу кодировщик для класса Row, а не для устранения ошибки. Наконец, я искал решение на Java, а не в Scala.
Ответы
Ответ 1
Ответ заключается в использовании RowEncoder и схемы набора данных с использованием TypeStruct.
Ниже приведен рабочий пример операции плоской карты с наборами данных:
StructType structType = new StructType();
structType = structType.add("id1", DataTypes.LongType, false);
structType = structType.add("id2", DataTypes.LongType, false);
ExpressionEncoder<Row> encoder = RowEncoder.apply(structType);
Dataset<Row> output = join.flatMap(new FlatMapFunction<Row, Row>() {
@Override
public Iterator<Row> call(Row row) throws Exception {
// a static map operation to demonstrate
List<Object> data = new ArrayList<>();
data.add(1l);
data.add(2l);
ArrayList<Row> list = new ArrayList<>();
list.add(RowFactory.create(data.toArray()));
return list.iterator();
}
}, encoder);
Ответ 2
У меня была та же проблема... Encoders.kryo(Row.class))
работал у меня.
В качестве бонуса, настройки настройки Apache Spark относятся к Kryo с тех пор, как он быстрее выполняет сериализацию "часто целых 10x":
https://spark.apache.org/docs/latest/tuning.html