简体   繁体   English

如何在Spark的Cassandra查询中使用java.time.LocalDate?

[英]How to use java.time.LocalDate in Cassandra query from Spark?

We have a table in Cassandra with column start_time of type date . 我们在Cassandra中有一个表,其start_time date类型。

When we execute following code: 当我们执行以下代码时:

val resultRDD = inputRDD.joinWithCassandraTable(KEY_SPACE,TABLE)
   .where("start_time = ?", java.time.LocalDate.now)

We get following error: 我们收到以下错误:

com.datastax.spark.connector.types.TypeConversionException: Cannot convert object 2016-10-13 of type class java.time.LocalDate to com.datastax.driver.core.LocalDate.
at com.datastax.spark.connector.types.TypeConverter$$anonfun$convert$1.apply(TypeConverter.scala:45)
at com.datastax.spark.connector.types.TypeConverter$$anonfun$convert$1.apply(TypeConverter.scala:43)
at com.datastax.spark.connector.types.TypeConverter$LocalDateConverter$$anonfun$convertPF$14.applyOrElse(TypeConverter.scala:449)
at com.datastax.spark.connector.types.TypeConverter$class.convert(TypeConverter.scala:43)
at com.datastax.spark.connector.types.TypeConverter$LocalDateConverter$.com$datastax$spark$connector$types$NullableTypeConverter$$super$convert(TypeConverter.scala:439)
at com.datastax.spark.connector.types.NullableTypeConverter$class.convert(TypeConverter.scala:56)
at com.datastax.spark.connector.types.TypeConverter$LocalDateConverter$.convert(TypeConverter.scala:439)
at com.datastax.spark.connector.types.TypeConverter$OptionToNullConverter$$anonfun$convertPF$29.applyOrElse(TypeConverter.scala:788)
at com.datastax.spark.connector.types.TypeConverter$class.convert(TypeConverter.scala:43)
at com.datastax.spark.connector.types.TypeConverter$OptionToNullConverter.com$datastax$spark$connector$types$NullableTypeConverter$$super$convert(TypeConverter.scala:771)
at com.datastax.spark.connector.types.NullableTypeConverter$class.convert(TypeConverter.scala:56)
at com.datastax.spark.connector.types.TypeConverter$OptionToNullConverter.convert(TypeConverter.scala:771)
at com.datastax.spark.connector.writer.BoundStatementBuilder$$anonfun$8.apply(BoundStatementBuilder.scala:93)

I've tried to register custom converters according to documentation : 我已经尝试根据文档注册自定义转换器:

object JavaLocalDateToCassandraLocalDateConverter extends TypeConverter[com.datastax.driver.core.LocalDate] {
  def targetTypeTag = typeTag[com.datastax.driver.core.LocalDate]
  def convertPF = { 
      case ld: java.time.LocalDate => com.datastax.driver.core.LocalDate.fromYearMonthDay(ld.getYear, ld.getMonthValue, ld.getDayOfMonth) 
      case _ => com.datastax.driver.core.LocalDate.fromYearMonthDay(1971, 1, 1) 
  }
}

object CassandraLocalDateToJavaLocalDateConverter extends TypeConverter[java.time.LocalDate] {
  def targetTypeTag = typeTag[java.time.LocalDate]
  def convertPF = { case ld: com.datastax.driver.core.LocalDate => java.time.LocalDate.of(ld.getYear(), ld.getMonth(), ld.getDay()) 
                    case _ => java.time.LocalDate.now 
  }
}

TypeConverter.registerConverter(JavaLocalDateToCassandraLocalDateConverter)
TypeConverter.registerConverter(CassandraLocalDateToJavaLocalDateConverter)

But it didn't help. 但它没有帮助。

How can I use JDK8 Date/Time classes in Cassandra queries executed from Spark? 如何在从Spark执行的Cassandra查询中使用JDK8 Date / Time类?

I think the simplest thing to do in a where clause like this is to just call 我认为在这样的where子句中最简单的事情就是调用

sc
 .cassandraTable("test","test")
 .where("start_time = ?", java.time.LocalDate.now.toString)
 .collect`

And just pass in the string since that will be a well defined conversion. 然后传入字符串,因为这将是一个定义良好的转换。

There seems to be an issue in the TypeConverters where your converter is not taking precedence over the built in converter. TypeConverters中似乎存在一个问题,即转换器不优先于内置转换器。 I'll take a quick look. 我快点看看。

--Edit-- - 编辑 -

It seems like the registered converters are not being properly transferred to the Executors. 似乎已注册的转换器未正确传输到执行程序。 In Local mode the code works as expected which makes me think this is a serialization issue. 在本地模式下,代码按预期工作,这使我认为这是一个序列化问题。 I would open a ticket on the Spark Cassandra Connector for this issue. 我会在Spark Cassandra Connector上打开这个问题的票。

Cassandra date format is yyyy-MM-dd HH:mm:ss.SSS Cassandra日期格式为yyyy-MM-dd HH:mm:ss.SSS

so you can use the below code, if you are using Java 8 to convert Cassandra date to LocalDate , then you can do your logic. 所以你可以使用下面的代码,如果你使用Java 8将Cassandra日期转换为LocalDate ,那么你可以做你的逻辑。

val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS")
val dateTime = LocalDateTime.parse(cassandraDateTime, formatter);

Or you can convert LocalDate to Cassandra date format and check it. 或者您可以将LocalDate转换为Cassandra日期格式并进行检查。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM