为什么自定义BaseRelation没有得到下推过滤器(在buildScan中)?

时间:2017-08-27 14:31:33

标签: java apache-spark apache-spark-sql

我正在使用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的filterwhere功能,但没有任何效果。

我还尝试了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)。

2 个答案:

答案 0 :(得分:2)

您应该简单地从您的MyRelation中删除其他合同,即TableScanPrunedScan,因为它们会阻碍并优先于PrunedFilteredScan

引用PrunedFilteredScan Contract — Relations with Column Pruning and Filter Pushdown

  

PrunedFilteredScanBaseRelations的协定,它支持列修剪(即消除不需要的列)和过滤器下推(即仅使用选定谓词进行过滤)。

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) { ... }