Spark + ElasticSearch returns RDD[(String, Map[String, Any])].我如何操纵 Any?

Spark + ElasticSearch returns RDD[(String, Map[String, Any])]. How can I manipulate Any?

Scala 2.10.4

弹性搜索 1.4.4

Spark 1.3

Elasticsearch-hadoop 2.1.0.Beta3

docs 之后,我能够从 ES 文档创建一个 rdd,如下所示:

val data sc.edRDD('indexName/type')

并且 returns 类型为

的元组的 RDD
(String, Map[String, Any])

其中 String 是文档 ID,Map 表示字段名为 String -> fieldvalue: Any 的 ES 文档。但是因为值类型是 Any,所以我不能做太多操作该数据。例如。如果我想

data.first()._2.get("someField")

字段值在ES中是double,在Spark中是Any。如果我打印这个值,它就像

Buffer(61.15)

尝试使用 .asInstanceOf[Double]、.toDouble 或它们的组合来转换它会产生如下异常:

java.lang.ClassCastException: scala.collection.convert.Wrappers$JListWrapper cannot be cast to java.lang.Double

在这个简单的案例中,正确的数据处理方法是什么?更糟糕的是,我真正想要的数据存在于嵌套文档中,这意味着原始 Map 中的 Any 类型值本身就是一个 Map[String, Any] 并且那些 Any 类型值有时是数字,有时是元组列表,具体取决于在钥匙上。

您遇到的问题是因为返回的类型 is a buffer - 不是 Double。

如果将其转换为 Buffer,则不会出现 class 转换异常。例如,在 ES 中索引以下文档:

{
    "myDouble" : 4.20,
    "myString" : "test",
    "myList" : [1.2, 93.2, 42.3]
}

然后从spark查询:

val documents = sc.esRDD("test/test", "?q=*")
val doc = documents.first()._2

println(doc.get("myDouble").get.asInstanceOf[Double]) # 4.2
println(doc.get("myString").get.asInstanceOf[String]) # test

import scala.collection.mutable.Buffer

println(doc.get("myList").get.asInstanceOf[Buffer[Double]]) 
# Buffer(1.2, 93.2, 42.3)

println(doc.get("myList").get.asInstanceOf[Buffer[Double]].mkString(","))
# 1.2,93.2,42.3