给出这样一个深层嵌套的实木复合地板结构
|-- bet: struct (nullable = true)
| |-- sides: array (nullable = true)
| | |-- element: struct (containsNull = true)
| | | |-- side: string (nullable = true)
| | | |-- betID: string (nullable = true)
| | | |-- secondarybetID: string (nullable = true)
| | | |-- parties: struct (nullable = true)
| | | | |-- partyIDs: array (nullable = true)
| | | | | |-- element: struct (containsNull = true)
| | | | | | |-- partyID: string (nullable = true)
| | | | | | |-- partyRole: integer (nullable = true)
| | | | | | |-- partySubGrp: struct (nullable = true)
| | | | | | | |-- partySubIDs: array (nullable = true)
| | | | | | | | |-- element: struct (containsNull = true)
| | | | | | | | | |-- partySubID: string (nullable = true)
| | | | | | | | | |-- partySubIDType: integer (nullable = true)
考虑到一个投注有多个方面,我们只对sides数组的第一方面感兴趣。 如何找到partyRole为10的一方所涉及的各方?
在prestosql中,我可以做类似
的操作 SELECT
filter(bet.sides[1].parties.partyids, x -> x.partyrole=10)[1] as party10
FROM
parquetbets
WHERE
cardinality(filter(bet.sides[1].parties.partyids, x -> x.partyrole=10))>0
如何在spark2 sql中执行相同的操作?
SELECT bet.sides[1] from parquetbets
在spark2 sql中,上述返回的数组没有对嵌套结构进行进一步修剪的范围?
即
SELECT bet.sides[1].parties from parquetbets
返回null。我已经尝试了一些组合,但是结果返回WrappedArrayElements,它们不提供查询嵌套数据的机制。 在prestosql中,返回的结果包含字段名称,以便轻松继续并更深入地探究结构。
有人可以指出我如何使用spark2 sql吗? 而且如果spark2 sql无法执行,那么spark数据帧如何做到这一点?
答案 0 :(得分:0)
傻问题:您是否考虑过将DataSet API与编码器一起使用?它提供了一个功能性API来对您的问题进行推理(这是一种更容易解决功能性的方法)。
否则,请考虑分解数组以对扁平化数据进行推理(请参阅org.apache.spark.sql.functions.explode)。
scala中的示例:
case class PartyId(partyID: String, partyRole: Int)
case class Party(partyIDs: Seq[PartyId])
case class Side(side: String, betId: String, parties: Party)
case class Bet(sides: Seq[Side])
import spark.implicits._
val ds = spark.read.load("my-bets.parquet").as[Bet]
val firstSidesDS = ds.flatMap(_.sides.headOption) //take the first side if exists
val result: Dataset[Side] = firstSidesDS.filter(_.parties.partyIDs.exists(_.partyRole == 10)) //Here I return sides for which there is at least a partyRole = 10