我正在使用Data Source API实现自己的数据源。
我使用了我在网上找到的几个文档,并提出了以下代码:
public class MyRelation extends BaseRelation implements TableScan, PrunedScan, PrunedFilteredScan {
public RDD<Row> buildScan(String[] requiredColumns, Filter[] filters) {
System.out.println(Arrays.toString(filters));
}
}
我使用以下查询获取空过滤器:
SELECT field1,field2,field3 from table WHERE field2>4 AND field3=1000
我跑了:
SQLContext sqc = new SQLContext(sparkContext);
Dataset<Row> sqlResult = sqc.sql( query ).where("field2 > 4").filter("field2 > 15");
正如您所看到的,我还尝试了API的filter
和where
功能,但没有任何效果。
我还尝试了unhandledFilters函数,它是空白的:
public Filter[] unhandledFilters(Filter[] filters)
{
System.out.println(Arrays.toString(filters));
return filters;
}
我希望得到过滤器&#34; field2&gt; 15&#34;和filters
数组中的其他人,但它是空白的。
任何想法我做错了什么以及如何解决这个问题?
P.S。我确实实现了TableScan和PrunedScan,并且调用了正确的方法,当我运行查询时没有where子句而且没有过滤器仍然会调用带过滤器的函数(继承自PrunedFilteredScan)。
答案 0 :(得分:2)
您应该简单地从您的MyRelation
中删除其他合同,即TableScan
和PrunedScan
,因为它们会阻碍并优先于PrunedFilteredScan
。
引用PrunedFilteredScan Contract — Relations with Column Pruning and Filter Pushdown:
PrunedFilteredScan
是BaseRelations
的协定,它支持列修剪(即消除不需要的列)和过滤器下推(即仅使用选定谓词进行过滤)。
这filter pushdown
部分是您所需要的,并且在Spark SQL 2.3中受PrunedFilteredScan
关系的支持。
提示:看看JDBCRelation是Apache Spark 2.3官方发行版中PrunedFilteredScan
的唯一实现。
答案 1 :(得分:1)
对于任何试图完成相同任务的人,我能够通过实施CatalystScan
接口来解决问题。 Catalyst是AQL查询优化机制,实现此接口并编写以下函数可以解决问题:
@Override
public RDD<Row> buildScan(Seq<Attribute> requiredColumns, Seq<Expression> filters) { ... }