Java SparkSession Hive SQL未应用regexp_replace

时间:2018-04-30 12:20:02

标签: java apache-spark hive

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

根据新要求,我需要从所选键中删除所有空格。

根据Apache documentation regexp_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未应用。 这可能是什么原因?

1 个答案:

答案 0 :(得分:3)

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

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

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

所以,这个Dataset<Row> 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")));
}

输出:

tet

要将\\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