文章目录
我们知道从Elasticsearch请求返回的数据是一条条的JSON格式的数据。那么我们要使用Spark加载Elasticsearch中的数据来进行处理计算,有哪些方法呢?
Elasticsearch提供了对Spark的支持,可以将ES中的索引加载为RDD或DataFrame。
在使用elasticsearch-spark插件之前,需要在项目中添加依赖:
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch-spark-20_2.11</artifactId>
<version>7.1.0</version>
</dependency>
Spark读Elasticsearch
1. ES索引加载为RDD
import org.elasticsearch.spark._
val spark = SparkSession
.builder()
.config("hive.metastore.uris", "thrift://master-1:9083")
//es配置
.config("es.nodes", "node-1")
.config("es.port", "9200")
.config("pushdown", "true")
.appName("Spark ES")
.enableHiveSupport()
.getOrCreate()
val rdd = spark.sparkContext.esJsonRDD("index_name")
//或者我们也可以添加第二个参数进行query(DSL)查询下推
val rdd = spark.sparkContext.esJsonRDD("index_name",
"""
|{
| "query":{
| "range":{
| "create_time":{
| "gte": "2021-01-01 00:00:00"
| "lt": "2021-03-01 00:00:00"
| }
| }
| }
|}
|""".stripMargin)
spark.close()
配置项"es.nodes"的值只要给出ES集群中的一个数据节点即可,只要给出一个节点,ES就能找到集群中的其他节点。数据节点就是ES安装目录下配置文件(…/elasticsearch-7.1.0/config/elasticsearch.yml)中"node.master"为true的节点。
Spark从ES加载出来的数据是JSON String类型的RDD,根据请求体的结构就可以取出来具体的数据。
2. ES索引加载为DataFrame
val spark = SparkSession
.builder()
.config("hive.metastore.uris", "thrift://master-1:9083")
.appName("Spark ES")
.enableHiveSupport()
.getOrCreate()
val options = Map(
"es.nodes" -> "node-1",
"es.port" -> "9200",
"pushdown" -> "true")
val df = spark.read.format("org.elasticsearch.spark.sql")
.options(options)
.load("index_name")
.where("col = 100")
.select("col1", "col2", "col3")
spark.close()
将ES索引加载成DataFrame后便可以方便地进行表操作了。
最后注意提交Spark任务时加上第三方依赖包elasticsearch-spark-20_2.11-7.1.0.jar。
Spark写Elasticsearch
1. Spark RDD写入ES索引
import org.elasticsearch.spark._
def rddToES(spark: SparkSession): Unit = {
val numbers = Map("one" -> 1, "two" -> 2, "three" -> 3)
val airports = Map("arrival" -> "Otopeni", "SFO" -> "San Fran")
spark.sparkContext
.makeRDD(Seq(numbers, airports))
.saveToEs("spark_es_demo")
}
1. Spark DataFrame写入ES索引
import org.elasticsearch.spark.sql._
def dfToES(spark: SparkSession): Unit = {
import spark.implicits._
val df = Seq((1, "a", 2), (1, "a", 2), (1, "b", 3))
.toDF("id", "category", "num")
df.saveToEs("spark_es_demo")
}