Spark Java中order by/sort不生效,如何实现指定规则的字母数字排序
Spark Java 字母数字混合字段自定义排序实现方案
默认的orderBy/sort函数按字典序排序时,ASCII码更小的数字字符会排在字母前面,因此无法得到你需要的字母开头内容优先的排序结果,可以通过两种方式实现需求:
方式1:自定义UDF实现排序(全版本兼容)
核心逻辑是给每条数据生成两个排序维度:
- 第一维度:字母开头的内容优先级更高,排序权重小于数字开头的内容
- 第二维度:同类型内容按原始字段的字典序升序排列
代码实现如下:
import org.apache.spark.sql.api.java.UDF1; import org.apache.spark.sql.types.DataTypes; import static org.apache.spark.sql.functions.*; // 注册排序优先级计算UDF spark.udf().register("calc_sort_priority", new UDF1<String, Integer>() { @Override public Integer call(String typValue) { if (typValue == null || typValue.trim().isEmpty()) { return 2; } // 字母开头返回权重0,数字开头返回权重1 return Character.isLetter(typValue.charAt(0)) ? 0 : 1; } }, DataTypes.IntegerType); // 执行排序 Dataset<Row> sortedDf = originalDf .orderBy( callUDF("calc_sort_priority", col("txtyp")).asc(), col("txtyp").asc() );
方式2:内置函数组合实现(Spark 3.0+适用)
无需自定义UDF,直接用正则提取函数判断首字符类型即可实现排序:
import static org.apache.spark.sql.functions.*; Dataset<Row> sortedDf = originalDf .orderBy( // 字母开头的匹配结果非空,对应判断结果为false(排序值0),优先级更高 regexp_extract(col("txtyp"), "^[A-Za-z]", 0).equalTo("").asc(), col("txtyp").asc() );
两种实现方式对样例数据排序后,都可以得到你期望的A1、A2、A3在前,1在后的输出结果。
内容的提问来源于stack exchange,提问作者Hemavathi
相关产品推荐
相关产品推荐

