elasticsearch Spark:使用ElasticSearch索引优化连接,elasticsearch,apache-spark,elasticsearch,Apache Spark" /> elasticsearch Spark:使用ElasticSearch索引优化连接,elasticsearch,apache-spark,elasticsearch,Apache Spark" />

elasticsearch Spark:使用ElasticSearch索引优化连接

elasticsearch Spark:使用ElasticSearch索引优化连接,elasticsearch,apache-spark,elasticsearch,Apache Spark,所以我正在学习通过ApacheSpark从ElasticSearch获取数据。 假设我已连接到具有“用户”索引的ElasticSearch sqlContext = SQLContext(sc) usersES=sqlContext.read.format('org.elasticsearch.spark.sql').option('es.nodes','mynode').load('users/user') explain(usersES)向我展示了以下内容: ==实际计划== 扫描Elas

所以我正在学习通过ApacheSpark从ElasticSearch获取数据。 假设我已连接到具有“用户”索引的ElasticSearch

sqlContext = SQLContext(sc)
usersES=sqlContext.read.format('org.elasticsearch.spark.sql').option('es.nodes','mynode').load('users/user')
explain(usersES)向我展示了以下内容:

==实际计划==

扫描ElasticsearchRelation(映射(es.nodes->mynode), es.resource-> 用户/用户),org.apache.spark.sql。SQLContext@6c78e806,无)[关于#145,活动#146,b日期#147, uid#148]

当我使用过滤器时:

usersES.filter(usersES.uid==1566324).explain()
==物理计划==过滤器(uid#203L=1566324) +-扫描ElasticsearchRelation(映射(es.nodes->mynode,es.resource-> 用户/用户),org.apache.spark.sql。SQLContext@6c78e806,无)[关于#145,活动#146,b日期#147,uid#148] PushedFilters:[EqualTo(uid,1566324)]

如您所见,Spark优雅地将过滤器推到ElasticSearch,使索引搜索快速而舒适

但是,当我尝试将用户加入另一个数据帧时,我总是遇到同样的问题: Spark扫描整个ElasticSearch索引,不推送我提供的任何过滤器。 例如:

a = sc.parallelize([1566324,1566329]).map(Row('id')).toDF()
a.join(usersES, usersES.uid==a.id).explain()
显示:

SortMergeJoin[id#210L],[uid#203L]:-Sort[id#210L ASC],false,0: +-TungsteneExchange哈希分区(id#210L,200),无:+-ConvertToUnsafe:+-Scan ExistingRDD[id#210L] +-排序[uid#203L ASC],false,0+-TungstenExchange散列分区(uid#203L,200),无 +-转炉安全 +-扫描ElasticsearchRelation(映射(es.nodes->mynode,es.resource-> 用户/用户),org.apache.spark.sql。SQLContext@6c78e806,无)[关于#145,活动#146,b日期#147,uid#148]


请告诉我,是否可以将Elasticsearch中的筛选器推送到联接中?

这是一种预期行为,是的,Elasticsearch hadoop连接器支持下推谓词,但在联接时没有下推

这是因为join操作不知道数据帧中键的分区方式

默认情况下,此操作将散列两个数据帧的所有密钥,通过网络将具有相同密钥散列的所有元素发送到同一台机器,然后将该机器上具有相同密钥的元素连接在一起

这就是为什么在没有按下谓词的情况下得到执行计划

编辑:从2.1版开始,连接器似乎支持IN子句。如果您的数据帧a不大,您应该使用它

  • 参考文献1
  • 参考文献2
谢谢!似乎这是唯一的方法,虽然不符合我的需要(in中从df到py的数千条记录),但唯一的方法是使用spark连接而不是in子句,或者您甚至可以使用广播变量。请您至少接受解决问题的答案,好吗?我也有类似的需要。我想我可以将其中一个数据帧放入广播变量中。如果是这种情况(广播哈希连接),Spark将使用Elastic的索引吗?@Avision您所说的“Spark使用Elastic的索引”是什么意思?