我有一个正在运行的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
未应用。
这可能是什么原因?
答案 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