【问题标题】:Java SparkSession Hive SQL is not applying regexp_replaceJava SparkSession Hive SQL 未应用 regexp_replace
【发布时间】:2019-08-23 20:29:24
【问题描述】:

我有一个正在运行的 Spark 应用程序执行配置单元查询。

有了新的要求,我需要删除所选键中的所有空格。

根据Apache documentationregexp_replace适合我的情况:

regexp_replace(string INITIAL_STRING, string PATTERN, string REPLACEMENT) 返回将 INITIAL_STRING 中与 PATTERN 中定义的 java 正则表达式语法匹配的所有子字符串替换为 REPLACEMENT 实例的字符串。 > 例如,regexp_replace("foobar", "oo|ar", "") 返回 'fb.' 请注意,在使用预定义字符类时需要注意:使用 '\s' 作为第二个参数将匹配字母 s; '\\s' 是匹配空格等所必需的。

运行这个:

public class SparkSql {

    private SparkSession session = SparkSession.builder()
            .appName("hive-sql")
            .config("spark.config.option", "configuration")
            .enableHiveSupport()
            .getOrCreate();

    // Omitted code here ...

    public void execute() {
        Dataset<Row> dataset = session.sql("select regexp_replace(master_key, '\\s+', ''") as key from master_table);
        JavaRDD<Row> rdd = context.parallelize(dataset.collectAsList(), factor);

        for (Row row : rdd.collect())
            System.out.println(row.getString(row.fieldIndex("key")));
    }
}

输出:

ABCD 100000

预期:

ABCD100000

由于某种原因,regexp_replace 未被应用。 这可能是什么原因?

【问题讨论】:

    标签: java apache-spark hive


    【解决方案1】:

    第一次尝试查找原因是检查查询是否可以在其他环境中运行。

    Hive Shell 返回select regexp_replace(master_key, '\\s+', '') 的预期结果。

    \ 是一个转义字符,如果 hive shell 需要一个转义字符,则将此表达式用作 Java String 将需要一个转义字符才能将 \ 传递给 SparkSession 的 SQL 解析器。

    所以,这个 Dataset&lt;Row&gt; dataset = session.sql("select regexp_replace(master_key, '\\s+', ''") as key from master_table); 实际上会将 \s+ 传递给 SQL 解析器:

    public void execute() {
        Dataset<Row> dataset = session.sql("select regexp_replace("test", '\\s+', ''") as key from master_table);
        JavaRDD<Row> rdd = context.parallelize(dataset.collectAsList(), factor);
    
        for (Row row : rdd.collect())
            System.out.println(row.getString(row.fieldIndex("key")));
    }
    

    输出:

    test
    

    要将\\s+ 传递给SparkSession 的SQL 解析器,我们需要为每个\ 添加一个转义\ 字符:

    public void execute() {
        Dataset<Row> dataset = session.sql("select regexp_replace(master_key, '\\\\s+', ''") as key from master_table);
        JavaRDD<Row> rdd = context.parallelize(dataset.collectAsList(), factor);
    
        for (Row row : rdd.collect())
            System.out.println(row.getString(row.fieldIndex("key")));
    }
    

    输出:

    ABCD100000
    

    【讨论】:

      猜你喜欢
      • 2020-02-15
      • 2020-01-13
      • 1970-01-01
      • 2016-02-23
      • 2019-03-18
      • 1970-01-01
      • 2018-09-20
      • 2020-04-11
      • 2019-06-28
      相关资源
      最近更新 更多