Если я правильно понял, вы ищете способ перебрать свою схему, и когда colorPair или eta вернет эти поля следующим образом:
plot.test.colorPair
plot.test.eta
plot.temp.colorPair
plot.temp.eta
Чтобы сгенерировать данные (схему) для вашего случая, я написал следующий код:
case class Eta(etaText: String, etaType: String, etaValue: String)
case class ColorPair(background: String, foreground: String)
case class Test(body: String, colorPair: ColorPair, eta: Eta, headline: String, plotType: String, priority: Long, plotCategory: String, productType: String, theme: String)
case class Temp(body: String, colorPair: ColorPair, eta: Eta ,headline: String, logo: String, plotType: String, priority: Long, plotCategory: String, productType: String, theme: String)
case class Plot(test: Test, temp: Temp)
case class Root(plotList: Array[String], plot: Plot)
def getSchema(): StructType ={
import org.apache.spark.sql.types._
import org.apache.spark.sql.catalyst.ScalaReflection
val schema = ScalaReflection.schemaFor[Root].dataType.asInstanceOf[StructType]
schema.printTreeString()
schema
}
Это будет иметь вывод:
root
|-- plotList: array (nullable = true)
| |-- element: string (containsNull = true)
|-- plot: struct (nullable = true)
| |-- test: struct (nullable = true)
| | |-- body: string (nullable = true)
| | |-- colorPair: struct (nullable = true)
| | | |-- background: string (nullable = true)
| | | |-- foreground: string (nullable = true)
| | |-- eta: struct (nullable = true)
| | | |-- etaText: string (nullable = true)
| | | |-- etaType: string (nullable = true)
| | | |-- etaValue: string (nullable = true)
| | |-- headline: string (nullable = true)
| | |-- plotType: string (nullable = true)
| | |-- priority: long (nullable = false)
| | |-- plotCategory: string (nullable = true)
| | |-- productType: string (nullable = true)
| | |-- theme: string (nullable = true)
| |-- temp: struct (nullable = true)
| | |-- body: string (nullable = true)
| | |-- colorPair: struct (nullable = true)
| | | |-- background: string (nullable = true)
| | | |-- foreground: string (nullable = true)
| | |-- eta: struct (nullable = true)
| | | |-- etaText: string (nullable = true)
| | | |-- etaType: string (nullable = true)
| | | |-- etaValue: string (nullable = true)
| | |-- headline: string (nullable = true)
| | |-- logo: string (nullable = true)
| | |-- plotType: string (nullable = true)
| | |-- priority: long (nullable = false)
| | |-- plotCategory: string (nullable = true)
| | |-- productType: string (nullable = true)
| | |-- theme: string (nullable = true)
Наконец, следующий код должен сгладить нужные поля:
def flattenSchema(schema: StructType, targetFields: List[String], prefix: String = null): Array[String]=
{
import org.apache.spark.sql.types._
schema.fields.flatMap(f => {
val colName = if (prefix == null) f.name else (prefix + "." + f.name)
f.dataType match {
case st : StructType =>
val found = st.filter(s => targetFields.contains(s.name))
if(found.isEmpty) {
flattenSchema(st, targetFields, colName)
}
else
found.flatMap(sf => {
val st = sf.dataType.asInstanceOf[StructType]
st.map(st => s"${colName}.${sf.name}.${st.name}")
})
case _ => Array[String]()
}
})
}
Приведенный выше код сканирует схему, чтобы найти поля, существующие в списке targetFields
, а затем использует flatMap
для извлечения схемы для этих полей.
Это должнобыть выводом:
plot.test.colorPair.background
plot.test.colorPair.foreground
plot.test.eta.etaText
plot.test.eta.etaType
plot.test.eta.etaValue
plot.temp.colorPair.background
plot.temp.colorPair.foreground
plot.temp.eta.etaText
plot.temp.eta.etaType
plot.temp.eta.etaValue