在Spark SQL中使用JSON路径

lnvxswe2  于 2023-08-06  发布在  Apache
关注(0)|答案(2)|浏览(106)

在Spark SQL中使用嵌套JSON时,可以使用JSON路径从JSON中提取数据吗?
例如:

{
    "store": {
        "book": [
            {
                "category": "reference",
                "author": "Nigel Rees",
                "title": "Sayings of the Century",
                "price": 8.95
            },
            {
                "category": "fiction",
                "author": "Evelyn Waugh",
                "title": "Sword of Honour",
                "price": 12.99
            },
            {
                "category": "fiction",
                "author": "Herman Melville",
                "title": "Moby Dick",
                "isbn": "0-553-21311-3",
                "price": 8.99
            },
            {
                "category": "fiction",
                "author": "J. R. R. Tolkien",
                "title": "The Lord of the Rings",
                "isbn": "0-395-19395-8",
                "price": 22.99
            }
        ],
        "bicycle": {
            "color": "red",
            "price": 19.95
        }
    },
    "expensive": 10
}

字符串
要使用json路径选择书籍类别引用的作者,我可以使用$.store.book[?(@.category == 'reference')].author
可以使用这样的操作来定义Spark表吗?

lokaqttq

lokaqttq1#

我不知道使用JSONPath来做你想要的事情的方法,但这里是我如何做到这一点:
1.引爆阵列
1.查询记录。
请注意,不必分解整个阵列。
代码:

package net.jgp.books.sparkInAction.ch12.lab920QueryOnJson;

import org.apache.spark.sql.Dataset;
import org.apache.spark.sql.Row;
import org.apache.spark.sql.SparkSession;
import org.apache.spark.sql.functions;

/**
 * Using JSONpath-like in SQL queries.
 * 
 * @author jgp
 */
public class QueryOnJsonApp {

  /**
   * main() is your entry point to the application.
   * 
   * @param args
   */
  public static void main(String[] args) {
    QueryOnJsonApp app = new QueryOnJsonApp();
    app.start();
  }

  /**
   * The processing code.
   */
  private void start() {
    // Creates a session on a local master
    SparkSession spark = SparkSession.builder()
        .appName("Query on a JSON doc")
        .master("local")
        .getOrCreate();

    // Reads a JSON, stores it in a dataframe
    Dataset<Row> df = spark.read()
        .format("json")
        .option("multiline", true)
        .load("data/json/store.json");

    // Explode the array
    df = df
        .withColumn("items", functions.explode(df.col("store.book")));

    // Creates a view so I can use SQL
    df.createOrReplaceTempView("books");
    Dataset<Row> authorsOfReferenceBookDf =
        spark.sql("SELECT items.author FROM books WHERE items.category = 'reference'");
    authorsOfReferenceBookDf.show(false);
  }
}

字符串
我认为这是一个很好的问题,我把它添加到Spark in Action的第12章。

jv4diomz

jv4diomz2#

spark确实提供了get_json_object函数,它可以通过JSONPath访问JSON主体,它应该以与您期望的相同的方式工作。
当然,如果你想从一个给定的JSON主体中隐式地生成一个表,分解或扁平化可能是更简单的方法,尽管你失去了对模式的控制-也就是说,如果JSON在某些行中有额外的键,你的模式将变得更宽。通过get_json_object使用一个你想提取并存储在列中的键列表对于生产用例来说会更干净。

相关问题