Java SparkSession Hive SQL не применяет regexp_replace

У меня есть работающее приложение Spark, выполняющее запросы кустов.

С новыми требованиями мне нужно удалить все пробелы из выбранного ключа.

По Документация Apache для моего случая подходит regexp_replace:

regexp_replace(string INITIAL_STRING, string PATTERN, string REPLACEMENT) Returns the string resulting from replacing all substrings in INITIAL_STRING that match the java regular expression syntax defined in PATTERN with instances of REPLACEMENT. > For example, regexp_replace("foobar", "oo|ar", "") returns 'fb.' Note that some care is necessary in using predefined character classes: using '\s' as the second argument will match the letter s; '\\s' is necessary to match whitespace, etc.

Запускаем это:

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 не применялся. Что могло быть причиной этого?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
0
223
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Первая попытка найти причину заключалась в том, чтобы проверить, можно ли выполнить запрос в других средах.

Hive Shell вернула ожидаемый результат для select regexp_replace(master_key, '\\s+', '').

\ - это escape-символ, и если оболочке улья требуется один escape-символ, при использовании этого выражения, поскольку Java String потребует еще один escape-символ для передачи \ в синтаксический анализатор SQL SparkSession.

Итак, этот 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")));
}

Выход:

test

Чтобы передать \\s+ в синтаксический анализатор SQL SparkSession, нам нужно добавить один escape-символ \ для каждого \:

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

Другие вопросы по теме