apache-spark - 为什么 array_contains 在 SQL 中接受两个参数的列,但在 Dataset API 中不接受?
问题描述
我一直在查看有关 StackOverflow 上array_contains
(和isin
)方法的问题和答案,但我仍然无法回答以下问题:
为什么array_contains
在 SQL 中接受列(引用)作为其参数,而标准函数不接受?
我可以理解,上述问题很容易被标记为“主要基于意见”或类似的,所以让我将其改写为以下内容:
如何使用array_contains
标准函数以便它接受列中的参数(值)?
scala> spark.version
res0: String = 2.3.0
val codes = Seq(
(Seq(1, 2, 3), 2),
(Seq(1), 1),
(Seq.empty[Int], 1),
(Seq(2, 4, 6), 0)).toDF("codes", "cd")
scala> codes.show
+---------+---+
| codes| cd|
+---------+---+
|[1, 2, 3]| 2|
| [1]| 1|
| []| 1|
|[2, 4, 6]| 0|
+---------+---+
// array_contains in SQL mode works with arguments being columns
val q = codes.where("array_contains(codes, cd)")
scala> q.show
+---------+---+
| codes| cd|
+---------+---+
|[1, 2, 3]| 2|
| [1]| 1|
+---------+---+
// array_contains standard function with Columns does NOT work. Why?!
// How to change it so it would work (without reverting to SQL expr)?
scala> val q = codes.where(array_contains($"codes", $"cd"))
java.lang.RuntimeException: Unsupported literal type class org.apache.spark.sql.ColumnName cd
at org.apache.spark.sql.catalyst.expressions.Literal$.apply(literals.scala:77)
at org.apache.spark.sql.functions$.array_contains(functions.scala:2988)
... 49 elided
解决方案
仅仅是因为没有人关心实现(Column, Column) => Column
变体。如果您检查源代码,您会发现设计中没有任何内容,这会阻止您创建一个,因为标准工作流程是将非Column
参数转换为文字。
它甚至不是特别有特色。还有其他没有包装器接受额外Column
参数的函数,包括但不限于不同的日期/时间处理函数和数学函数。
推荐阅读
- c++ - 什么是正确的格式以及如何在 .bin 文件中正确组织字节以在 char 数组 [] 中设置?
- javascript - 将 api 调用中的道具发送到另一个反应组件时遇到问题
- c# - 通过 Nuke.Common/NuGet.CommandLine 部署 NuGet 包时如何通过 Azure Auth
- node.js - 使用 node.js 提供图像的 WebServer
- reactjs - 将 aria-role 传递给 Material UI
零件 - javascript - 为什么需要将 Tealium utag 脚本动态添加到页面中?
- javascript - 创建反应应用程序:setupProxy 不断返回被 CORS 策略阻止的 401,不适用于远程 URL?
- python - Groupby,转换 - 恢复到原始表
- java - 使用 Java 打印 API 打印多页(可能是打印机或 PDF)文档时出现错误的迭代
- ssl - Pickle 一个 python 请求会话以在不同的应用程序运行中实现“TLS 会话恢复”