使用嵌套结构字段过滤


|-- data: struct (nullable = true)
 |    |-- keyNote: struct (nullable = true)
 |    |    |-- key: string (nullable = true)
 |    |    |-- note: string (nullable = true)

在上面的示例结构中,如何在structs数据和主题演讲中选择注释字段?

我需要用两个不同的数据帧过滤,似乎无法选择一个嵌套字段。我正在使用 Spark 1.6.2 没有左抗的位置,因此我使用了以下过滤器。以下是我尝试过的两种方式。

val dataFrame = esData.join(broadcastDataFrame, esData.select(esData.col("data.keyNote")).col("note") !== broadcastDataFrame("id")) 
Error: Cannot resolve column name "note" among (keyNote)

val dataFrame = esData.join(broadcastDataFrame, esData.select(esData.col("data.keyNote.*")).col("note") !== broadcastDataFrame("id")) 
Error: No such struct field * in key, note

val dataFrame = esData.join(broadcastDataFrame, esData("data.keyNote.note") !== broadcastDataFrame("id")) 
java.lang.IllegalArgumentException: Field "note" does not exist.(..)

val dataFrame = esData.join(broadcastDataFrame, esData.select($"data.keyNote.note").col("note") !== broadcastDataFrame("id")) 
Error: resolved attribute(s) note#9 missing from data#1,id#3 in operator !Join Inner, Some(NOT (note#9 = id#3))

使用的数据框是从弹性搜索(伪像:弹性spark-13_2.10,版本:5.1.1 )创建的

val dataFrameES = context.read.format("org.elasticsearch.spark.sql")
   .options(Map("es.read.field.exclude" ->
    "<Excluding All the fields except those I need>"))
   .load("<Index>/<Type>") 

现在,我尝试使用es.read.field.include,但是除了排除其他所有内容外,我尝试过的任何东西都无法检索嵌套的项目。我试图包括以下内容;数据,data.keynote,data.keynote.key,以及每个置换率加上 *之后的通配符。我不确定这是火花的东西还是弹性搜索的东西。

我认为这是读数错误的,直到我排除了所有不需要的领域并成功地检索了我想要的那些领域。

我现在认为这是加入,因为我能够在这样的过滤器中没有错误抓住该字段;

 esData.filter(esData("data.keyNote.key").equalTo("x")) 

当我尝试完成上面的加入时,我只是继续遇到错误,这是我有两个数据集所需的。当我在创建弹性搜索数据框架后立即运行过滤器时,要比运行卷发要长得多。

正确的语法是:

df1.join(df2, df1("x.y.z") !== df2("v"))

df1.join(df).where(df1("x.y.z") !== df2("v")

完整示例

scala> :paste
// Entering paste mode (ctrl-D to finish)
val esData = sqlContext.read.json(sc.parallelize(Seq(
  """{"data": {"keyNote": {"key":   "foo", "note": "bar"}}}""")))
val broadcastDataFrame = Seq((1L, "foo"), (2L, "bar")).toDF("n", "id")
esData.join(
  broadcastDataFrame, esData("data.keyNote.note") !== broadcastDataFrame("id")
).show
// Exiting paste mode, now interpreting.
+-----------+---+---+
|       data|  n| id|
+-----------+---+---+
|[[foo,bar]]|  1|foo|
+-----------+---+---+
esData: org.apache.spark.sql.DataFrame = [data: struct<keyNote:struct<key:string,note:string>>]
broadcastDataFrame: org.apache.spark.sql.DataFrame = [n: bigint, id: string]

如果您想要antijoin,最好使用外部连接和过滤 nulls

相关内容

  • 没有找到相关文章

最新更新