【问题标题】:Query A Nested Array in Parquet Records查询 Parquet 记录中的嵌套数组
【发布时间】:2016-09-13 05:36:33
【问题描述】:

我正在尝试不同的方法来查询记录数组中的记录并将完整的行显示为输出。

我不知道哪个嵌套对象有字符串“pg”。但我想查询特定对象。对象是否有“pg”。如果“pg”存在,那么我想显示完整的行。如何在不指定对象索引的情况下在嵌套对象上编写“spark sql 查询”。所以我不想使用 children.name 的索引

我的 Avro 记录:

{
"name": "Parent",
"type":"record",
"fields":[
    {"name": "firstname", "type": "string"},

    {
        "name":"children",
        "type":{
            "type": "array",
            "items":{
                        "name":"child",
                        "type":"record",
                        "fields":[
                            {"name":"name", "type":"string"}
                        ]
                    }
            }
    }
]
}

我正在使用 Spark SQL 上下文来查询读取的数据帧。 所以如果输入是

Row no   Firstname Children.name
    1    John       Max
                    Pg
    2    Bru        huna
                    aman

输出应该返回 poq 1,因为它有行,其中 children.name 的一个对象是 pg。

val results = sqlc.sql("SELECT firstname, children.name FROM nestedread where children.name = 'pg'")
results.foreach(x=> println(x(0), x(1).toString))

上述查询无效。但它在我查询 children[1].name 时有效。

我还想知道我是否可以过滤一组记录然后爆炸。而不是首先分解并创建大量行然后过滤。

【问题讨论】:

  • children 是一个数组,children.name 没有任何意义。 children[1].name 意味着您访问该数组中的第一个对象,并读取 name 属性。
  • 是的。但我想查询特定对象。对象是否有 pg。如果 pg 存在,那么我想显示完整的行。如何在不指定对象索引的情况下对嵌套对象编写“sql 查询”。
  • 你检查过这个吗:bender.io/2013/09/22/…
  • 如果提供的答案解决了您的问题,请接受以关闭问题!

标签: apache-spark apache-spark-sql hiveql spark-dataframe parquet


【解决方案1】:

好像可以用

org.apache.spark.sql.functions.explode(e: Column): Column

例如在我的项目中(在 java 中),我有这样的嵌套 json:

{
    "error": [],
    "trajet": [
        {
            "something": "value"
        }
    ],
    "infos": [
        {
            "something": "value"
        }
    ],
    "timeseries": [
        {
            "something_0": "value_0",
            "something_1": "value_1",
            ...
            "something_n": "value_n"
        }
    ]
}

我想分析“时间序列”中的数据,所以我做了:

DataFrame ts = jsonDF.select(org.apache.spark.sql.functions.explode(jsonDF.col("timeseries")).as("t"))
                     .select("t.something_0",
                             "t.something_1",
                             ...
                             "t.something_n");

我也是火花新手。希望这能给你一个提示。

【讨论】:

  • 嗨,谢谢。我找到了通过 Explode 的方法。 val results = sqlc.sql("SELECT firstname, child.name, FROM parent LATERAL VIEW explode(children) childTable AS child")
  • 我还想知道我是否可以过滤一组记录然后爆炸。而不是首先分解并创建大量行然后过滤。
【解决方案2】:

问题解决了

我找到了通过 Explode 的方法。

val results = sqlc.sql("SELECT firstname, child.name, FROM parent LATERAL VIEW explode(children) childTable AS child 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-13
    相关资源
    最近更新 更多