我正在尝试编写一个udf或者只是一些sql查询来获取嵌套Struct的值。
架构:
StructType(StructField(Parameters,ArrayType(StructType(StructField(**Name**,StringType,true), StructField(Value,StringType,true)),true),true))
我想访问名称的值,并过滤掉名称不在的数据(“BOB”,“Jone”,“Adam”)。< / p>
出于规模目的,爆炸对我来说太慢了。我需要更好的表现。
由于
答案 0 :(得分:0)
您甚至可以在列名中使用点(.
)在数组中引用嵌套列 - 然后创建一个简单的UDF来检查其中一个值是否与您的&#34;有趣的名称相匹配&#34;名单。类似的东西:
import org.apache.spark.sql.functions._
import spark.implicits._
// "df" contains some data with the right schema:
df.printSchema()
// root
// |-- Parameters: array (nullable = true)
// | |-- element: struct (containsNull = true)
// | | |-- Name: string (nullable = true)
// | | |-- Value: string (nullable = true)
df.show()
// +--------------------+
// | Parameters|
// +--------------------+
// | [[Bob,1], [Jane,2]]|
// |[[Adam,1], [Jane,6]]|
// |[[Joan,3], [John,5]]|
// +--------------------+
// we only want the record where names include these:
val interestingNames = Seq("Bob", "Adam")
// UDF checking if there's an intersection between given sequence of names and "interesting" ones:
val areNamesIncluded = udf {
names: Seq[String] => names.intersect(interestingNames).nonEmpty
}
// use "where" with the result of applying this UDF to Parameters.Name:
val result = df.where(areNamesIncluded($"Parameters.Name"))
result.show()
// +--------------------+
// | Parameters|
// +--------------------+
// | [[Bob,1], [Jane,2]]|
// |[[Adam,1], [Jane,6]]|
// +--------------------+
你可以在没有UDF的情况下实现这一点,使用array_contains
函数对每个有趣的名称&#34;然后使用||
折叠结果:
val result2 = df.where(interestingNames.map(s => array_contains($"Parameters.Name", s)).fold(lit(false))(_ || _))