Apache spark spark2 sql带拼花地板的深嵌套数组结构

Apache spark spark2 sql带拼花地板的深嵌套数组结构,apache-spark,apache-spark-sql,parquet,trino,spark2,Apache Spark,Apache Spark Sql,Parquet,Trino,Spark2,给定一个像这样的深嵌套拼花地板结构 |-- bet: struct (nullable = true) | |-- sides: array (nullable = true) | | |-- element: struct (containsNull = true) | | | |-- side: string (nullable = true) | | | |-- betID: string (nullable = true) |

给定一个像这样的深嵌套拼花地板结构

|-- 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)
考虑到一个赌注有好几方,不知何故,我们只对双方数组中的第一方感兴趣。 我怎样才能找到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
我如何在Spark2SQL中进行同样的操作

 SELECT bet.sides[1] from parquetbets 
在SPARK2SQL中,上面返回的数组在嵌套结构上没有进一步修剪的范围

i、 e

返回null。我尝试了几种组合,但结果返回WrappedArray元素,这些元素不提供查询嵌套数据的机制。 在prestosql中,返回的结果包含字段名,因此很容易继续并深入研究结构

有人能告诉我Spark2SQL是如何支持这一点的吗?
如果spark2 sql不能做到这一点,那么spark dataframes如何做到这一点呢?

愚蠢的问题:您考虑过将DataSet API与编码器一起使用吗?它提供了一个功能性API来对您的问题进行推理(这是一种更容易从功能上解决的方法)

否则,请考虑将数组展开为扁平化数据(参见org .APACHEC.SPACK.SQL.Fort.ExcDe).< /P> 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

你能举个例子说明如何做到这一点吗?你使用的是Scala、Java还是Python?刚刚添加了一个使用Scala和Dataset API的例子,使用的是spark sql和Java。我想通过编写sql来演示sparksqls查询拼花地板数据的能力。在这种情况下,它似乎有不足之处。Prestosql按预期工作。我有点失望sparksql返回包装的数组,这无助于进一步“发现”数据。谢谢,我会尝试一下你所建议的,虽然这会导致我再次使用编码器来描述模式,这似乎与已经有了模式的直观性背道而驰?
  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