Статьи

Apache Spark Packages, от XML до JSON

Сообщество Apache Spark приложило много усилий для расширения Spark. Недавно мы хотели преобразовать набор данных XML в нечто, что было бы проще запрашивать. Мы были в основном заинтересованы в исследовании данных на основе миллиардов транзакций, которые мы получаем каждый день. XML является широко известным форматом, но иногда с ним может быть сложно работать. Например, в Apache Hive мы можем определить структуру схемы нашего XML, а затем запросить ее с помощью SQL.

Однако нам было трудно следить за изменениями в структуре XML, поэтому предыдущая опция была отклонена. Мы использовали возможности Spark Streaming для переноса этих транзакций в наш кластер, и мы думали сделать необходимые преобразования в Spark. Однако осталась та же проблема: нам приходилось менять наше приложение Spark каждый раз, когда менялась структура XML.

Должен быть другой путь!

Существует сообщество Apache Spark от сообщества, которое мы могли бы использовать для решения этих проблем. В этом посте я расскажу, как использовать пакет Apache Spark от сообщества для чтения любого XML-файла в DataFrame.

Давайте загрузим оболочку Spark и посмотрим пример:

1
./spark-shell — packages com.databricks:spark-xml_2.10:0.3.3

Здесь мы только что добавили пакет XML в нашу среду Spark. Это, конечно, можно добавить, когда вы пишете приложение Spark и упаковываете его в файл JAR.

Используя пакет, мы можем прочитать любой XML-файл в DataFrame. При загрузке DataFrame мы могли бы указать схему наших данных, но это было нашей главной задачей в первую очередь, поэтому мы позволим Spark сделать вывод. Вывод схемы DataFrame является очень мощным приемом, поскольку нам больше не нужно знать схему, чтобы она могла измениться в любое время.

Давайте посмотрим, как мы загружаем наши XML-файлы в DataFrame:

1
2
3
4
5
6
7
val df = sqlContext
          .read
          .format("com.databricks.spark.xml")
          .option("rowTag", "OrderSale")
          .load("~/transactions_xml_folder/")
           
df.printSchema

Печать схемы DataFrame дает нам представление о том, что сделала система логического вывода.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
root
 |-- @ApplicationVersion: string (nullable = true)
 |-- @BusinessDate: string (nullable = true)
 |-- @Change: double (nullable = true)
 |-- @EmployeeId: long (nullable = true)
 |-- @EmployeeName: string (nullable = true)
 |-- @EmployeeUserId: long (nullable = true)
 |-- @MealLocation: long (nullable = true)
 |-- @MessageId: string (nullable = true)
 |-- @OrderNumber: long (nullable = true)
 |-- @OrderSourceTypeId: long (nullable = true)
 |-- @PosId: long (nullable = true)
 |-- @RestaurantType: long (nullable = true)
 |-- @SatelliteNumber: long (nullable = true)
 |-- @SpmHostOrderCode: string (nullable = true)
 |-- @StoreNumber: long (nullable = true)
 |-- @TaxAmount: double (nullable = true)
 |-- @TaxExempt: boolean (nullable = true)
 |-- @TaxInclusiveAmount: double (nullable = true)
 |-- @TerminalNumber: long (nullable = true)
 |-- @TimeZoneName: string (nullable = true)
 |-- @TransactionDate: string (nullable = true)
 |-- @TransactionId: long (nullable = true)
 |-- @UTCOffSetMinutes: long (nullable = true)
 |-- @Version: double (nullable = true)
 |-- Items: struct (nullable = true)
 |    |-- MenuItem: struct (nullable = true)
 |    |    |-- #VALUE: string (nullable = true)
 |    |    |-- @AdjustedPrice: double (nullable = true)
 |    |    |-- @CategoryDescription: string (nullable = true)
 |    |    |-- @DepartmentDescription: string (nullable = true)
 |    |    |-- @Description: string (nullable = true)
 |    |    |-- @DiscountAmount: double (nullable = true)
 |    |    |-- @Id: long (nullable = true)
 |    |    |-- @PLU: long (nullable = true)
 |    |    |-- @PointsRedeemed: long (nullable = true)
 |    |    |-- @Price: double (nullable = true)
 |    |    |-- @PriceLessIncTax: double (nullable = true)
 |    |    |-- @PriceOverride: boolean (nullable = true)
 |    |    |-- @ProductivityUnitQuantity: double (nullable = true)
 |    |    |-- @Quantity: long (nullable = true)
 |    |    |-- @TaxAmount: double (nullable = true)
 |    |    |-- @TaxInclusiveAmount: double (nullable = true)
 |-- OrderTaxes: struct (nullable = true)
 |    |-- TaxByImposition: struct (nullable = true)
 |    |    |-- #VALUE: string (nullable = true)
 |    |    |-- @Amount: double (nullable = true)
 |    |    |-- @ImpositionId: long (nullable = true)
 |    |    |-- @ImpositionName: string (nullable = true)
 |-- Payments: struct (nullable = true)
 |    |-- Payment: struct (nullable = true)
 |    |    |-- #VALUE: string (nullable = true)
 |    |    |-- @AccountIDLast4: string (nullable = true

На этом этапе мы можем использовать любой инструмент SQL для запроса нашего XML с использованием Spark SQL. Прочтите этот пост ( Apache Spark как распределенный движок SQL ), чтобы узнать больше о Spark SQL. Идя дальше, мы могли бы использовать инструменты, которые могут читать данные в формате JSON. Наличие наборов данных JSON особенно полезно, если у вас есть что-то вроде Apache Drill .

Если у вас есть какие-либо вопросы об использовании этого пакета Apache Spark для чтения XML-файлов в DataFrame, задайте их в разделе комментариев ниже.

Ссылка: Apache Spark Packages, от XML до JSON от нашего партнера JCG Чейза Хули в блоге Mapr .