Spark Java中如何使用and()、or()函数分组带优先级的布尔表达式
Java Spark 带逻辑优先级的过滤条件实现
Spark 的 Column 类提供的 and()、or() 方法本身没有内置的运算符优先级匹配规则,所有逻辑表达式的分组、优先级完全依靠方法的嵌套调用关系实现,和原生表达式的括号层级一一对应——被作为参数传入其他逻辑方法的表达式,会优先完成计算。
对应两种目标表达式的实现方式
以下默认已经通过 org.apache.spark.sql.functions.col 拿到对应列的 Column 实例。
1. 匹配 ((col1 && col2) || col3) 的逻辑
该表达式的计算顺序为:先执行 col1 && col2 的与判断,再将判断结果和 col3 执行或判断。
- 分步拆分写法:
- 先封装内层的与逻辑:
Column innerAnd = col("col1").and(col("col2")) - 再封装外层的或逻辑:
Column filterCondition = innerAnd.or(col("col3"))
- 先封装内层的与逻辑:
- 等价链式写法:因为内层与的返回值本身就是
Column类型,可以直接在方法调用后接外层或逻辑,即col("col1").and(col("col2")).or(col("col3")),和分步写法完全等价。
2. 匹配 (col1 && (col2 || col3)) 的逻辑
该表达式的计算顺序为:先执行 col2 || col3 的或判断,再将判断结果和 col1 执行与判断。
注意:这种嵌套不能直接用无层级的链式写法实现,如果直接写
col("col1").and(col("col2")).or(col("col3")),得到的是上一种表达式的逻辑,和目标逻辑完全不一致。
- 正确实现写法:
- 先封装内层的或逻辑:
Column innerOr = col("col2").or(col("col3")) - 再封装外层的与逻辑:
Column filterCondition = col("col1").and(innerOr)
这种写法本质上就是把内层的或逻辑作为参数传入外层的与方法,等价于原表达式里的括号分组效果。
- 先封装内层的或逻辑:
通用实现规则
如果要实现任意带括号分组的复杂逻辑,只需要对照原表达式的括号层级做对应嵌套即可:
- 括号内优先计算的子逻辑,单独封装为
Column实例 - 把封装好的子逻辑,作为外层逻辑运算方法的传入参数
- 最终得到的
filterCondition可以直接传入Dataset.filter()方法完成过滤
内容的提问来源于stack exchange,提问作者Vamen95
相关产品推荐
相关产品推荐

