我对Spark和Scala都不熟悉。我在互联网上读过一些文章。我成功地使用Spark从Elasticsearch获取文档,但我仍然坚持如何从文档中提取字段。
我有33,617份文件:
import ...
val conf = new JobConf()
conf.set("es.resource", "index-name/type-name")
conf.set("es.nodes", "hostname1:9200,hostname2:9200")
conf.set("es.query", "{...}")
val esRDD = sc.newAPIHadoopRDD(conf, classOf[EsInputFormat[Text, MapWritable]], classOf[Text], classOf[MapWritable])
scala> esRDD.count() // That's GOOD!
res11: Long = 33617
scala> esRDD.take(5).foreach(row => println(row._2))
{@version=1, field1=a, ...}
{@version=1, field1=a, ...}
{@version=1, field1=b, ...}
{@version=1, field1=b, ...}
{@version=1, field1=b, ...}
我不知道如何在Scala中使用org.apache.hadoop.io.MapWritable
。
// Error!!
scala> esRDD.take(5).foreach(row => println(row._2("field1")))
error: org.apache.hadoop.io.MapWritable does not take parameters
esRDD.take(5).foreach(row => println(row._2("field1")))
// Oops. null is printed
scala> esRDD.take(5).foreach(row => println(row._2.get("field1")))
null
null
null
null
null
我的最终目标是按field1
汇总并打印他们的计数:
scala> esRDD.groupBy(???).mapValues(_.size)
Map(a => 2, b => 3) // How to get this output??
但是,我无法弄明白。
$ bin/spark-shell --master local --jars jars/elasticsearch-spark_2.11-2.2.0.jar
scala> import org.elasticsearch.spark._
scala> val rdd: RDD[(String, Map[String, Any])] = sc.esRDD("index-name/type-name")
<console>:45: error: not found: type RDD
val rdd: RDD[(String, Map[String, Any])] = sc.esRDD("index-name/type-name")
^
scala> sc.esRDD("index-name/type-name")
java.lang.NoSuchMethodError: scala.Predef$.ArrowAssoc(Ljava/lang/Object;)Ljava/lang/Object;
at org.elasticsearch.spark.rdd.EsSpark$.esRDD(EsSpark.scala:26)
at org.elasticsearch.spark.package$SparkContextFunctions.esRDD(package.scala:20)
答案 0 :(得分:1)
Elasticsearch-hadoop对Spark有本机支持,我建议使用它 - API更简单:
import org.elasticsearch.spark._
val rdd: RDD[(String, Map[String, Any])] = sc.esRDD("index-name/type-name")
这是一个简单的元组rdd,其中键是文档ID,Map代表ES文档。
您可以将其映射到不同的元组:
val mapped = rdd.map{ case(id, doc) => (doc.get("field1").get, 1) }
我放1,因为看起来你不需要doc
其他任何地方。然后执行groupByKey
和地图:
mapped.groupByKey().map{ case(key,val) => (key, val.size) }
此外,如果您只使用Spark连接器,则不需要整个es-hadoop依赖项,这相当大,您只需使用elasticsearch-spark
有关详细信息,请查看documentation。