1、前言
Spark操作数据写入es,可以参考官方案例来操作
Apache Spark support | Elasticsearch for Apache Hadoop [7.14] | Elastic
本博客,讲挑选其中的一种方法进行讲解。
2、方法
JavaEsSpark类中,提供了四大类方法把数据写入到es中。
1、saveToEs 使用Elasticsearch -hadoop,任何RDD都可以保存到Elasticsearch,只要它的内容可以翻译成documents(es的doc)。在实践中,这意味着RDD类型需要是Map(无论是Scala还是Java)、JavaBean或Scala case类。当情况并非如此时,可以很容易地在Spark中转换数据或插入自己的符合要求的RDD类型数据。 此方法一共提供了如下三种入参方法: def saveToEs(jrdd: JavaRDD[_], resource: String) = EsSpark.saveToEs(jrdd.rdd, resource) def saveToEs(jrdd: JavaRDD[_], resource: String, cfg: JMap[String, String]) = EsSpark.saveToEs(jrdd.rdd, resource, cfg.asScala) def saveToEs(jrdd: JavaRDD[_], cfg: JMap[String, String]) = EsSpark.saveToEs(jrdd.rdd, cfg.asScala)
2、saveToEsWithMeta
Elasticsearch允许每个文档拥有自己的元数据。如上所述,可以通过各种映射选项定制这些参数,以便从属于它们的文档中提取它们的值。此外,还可以包括/排除哪些数据被发送回Elasticsearch。在Spark中,elasticsearch-hadoop扩展了这一功能,允许通过使用pair rdd在文档本身之外提供元数据。换句话说,对于包含键-值元组的rdd,可以从用作文档源的键和值中提取元数据。
元数据是通过org.elasticsearch.spark.rdd包中的metadata Java enum来描述的,它标识了它的类型- id, ttl, version等等。如果RDD key不是Map类型的,那么elasticsearch-hadoop会将该对象视为代表文档id的对象,并相应地使用它。
此方法同样一共提供了如下三种入参方法:
def saveToEsWithMeta[K, V](jrdd: JavaPairRDD[K, V], resource: String) = EsSpark.saveToEsWithMeta(jrdd.rdd, resource) def saveToEsWithMeta[K, V](jrdd: JavaPairRDD[K, V], resource: String, cfg: JMap[String, String]) = EsSpark.saveToEsWithMeta(jrdd.rdd, resource, cfg.asScala) def saveToEsWithMeta[K, V](jrdd: JavaPairRDD[K, V], cfg: JMap[String, String]) = EsSpark.saveToEsWithMeta(jrdd.rdd, cfg.asScala)
3、saveJsonToEs
对于RDD中的数据已经是JSON格式的情况,elasticsearch-hadoop允许直接索引而不需要应用任何转换;数据被原样接收并直接发送到Elasticsearch。因此,在本例中,elasticsearch-hadoop需要一个包含String或字节数组(byte[]/Array[byte])的RDD,假设每个条目代表一个JSON文档。如果RDD没有正确的签名,就不能应用saveJsonToEs方法(在Scala中它们是不可用的)。
此方法同样一共提供了如下三种入参方法:
def saveJsonToEs(jrdd: JavaRDD[String], resource: String) = EsSpark.saveJsonToEs(jrdd.rdd, resource) def saveJsonToEs(jrdd: JavaRDD[String], resource: String, cfg: JMap[String, String]) = EsSpark.saveJsonToEs(jrdd.rdd, resource, cfg.asScala) def saveJsonToEs(jrdd: JavaRDD[String], cfg: JMap[String, String]) = EsSpark.saveJsonToEs(jrdd.rdd, cfg.asScala)
4、saveJsonByteArrayToEs
对于那种是字节数组的JsonRDD,同理如saveJsonToEs一样
def saveJsonByteArrayToEs(jrdd: JavaRDD[Array[Byte]], resource: String) = EsSpark.saveJsonToEs(jrdd.rdd, resource) def saveJsonByteArrayToEs(jrdd: JavaRDD[Array[Byte]], resource: String, cfg: JMap[String, String]) = EsSpark.saveJsonToEs(jrdd.rdd, resource, cfg.asScala) def saveJsonByteArrayToEs(jrdd: JavaRDD[Array[Byte]], cfg: JMap[String, String]) = EsSpark.saveJsonToEs(jrdd.rdd, cfg.asScala)
3、代码实战
3.1参数设置
//设置es的参数
conf.set("es.nodes", esNodes);
conf.set("es.port", port);
conf.set("es.net.http.auth.user", userName);
conf.set("es.net.http.auth.pass", passWd);
conf.set("es.nodes.discovery", "false");
conf.set("org.elasticsearch.spark.sql", "true");
conf.set("out.es.batch.size.entries", "1000");
conf.set("es.nodes.wan.only", "true");
3.2写入代码
SparkSession sparkSession = SparkSession.builder().config(conf).getOrCreate();
Dataset<Row> rowDataset = sparkSession.sql(sql);
Dataset<String> stringDataset = rowDataset.toJSON();
JavaEsSpark.saveJsonToEs(stringDataset.javaRDD(), resource);