マップスキーマタイプを使う
マップスキーマは、キーと値を含むエントリーの配列です。
マップを作成
SELECT ENTRY句を使って既存のデータからマップを作成できます。これにより、キーとして使用する識別子または式、および値として使用する識別子、式、サブクエリーを定義できるようになります。句は次のように書式設定します:
SELECT ENTRY {
key = expression,
value = expression or sub-query
}
次の構文を使えば、マップのキーまたは値として暗黙的に識別子を割り当てられます:このケースでは、最初の識別子の値がキーとして使われ、2番目の識別子の値が値として使われています。マップエレメントが少なくとも1つ明示的に割り当てられていれば、順序は重要ではありません。
SELECT ENTRY {
key identifier, value identifier
}
たとえば次の入力データでは:
{
"order":[
{
"orderno":1001,
"custid":"C41",
"order_date":"2017-04-29",
"ship_date":"2017-05-03",
"items":[
{
"itemno":347,
"qty":5,
"price":19.99
},
{
"itemno":193,
"qty":2,
"price":28.89
}
]
},
{
"orderno":1002,
"custid":"C13",
"order_date":"2017-05-01",
"ship_date":"2017-05-03",
"items":[
{
"itemno":460,
"qty":95,
"price":100.99
},
{
"itemno":680,
"qty":150,
"price":8.75
}
]
}
]
}
次のクエリーを使えば、キーがordernoエレメントであり、値がitemnoエレメントの配列であるマップを作成できます:
FROM order
SELECT ENTRY {
value = (
FROM items
SELECT itemno
),
orderno
}
このケースでは、次の結果が返されます。
{
"1001":[
347,
193
],
"1002":[
460,
680
]
}
toMapファンクションを使い、レコードをマップに変換することもできます。たとえば、上記で使用した入力値で、次のクエリーによってorderレコードをマップに変換できます。それにより、map_identifier['key']という構文でキーを使い、マップエレメントを呼び出すことができるようになります。
FROM order AS o
LET $o = toMap(o)
SELECT {
id = concatWith('-',$o['custid'], $o['orderno']),
total = (
FROM items
SELECT sum(price)
)
}
以下の結果が返されます:
[
{
"id":"C41-1001",
"total":48.88
},
{
"id":"C13-1002",
"total":109.74
}
]
toMapファンクションの詳細は、特別ファンクションをご覧ください。
マップを読み取る
データにマップが含まれている場合、クエリーでそのキーと値を選択できます。たとえば、propertiesという名前の入力に次のデータが含まれているとします:次のAvroスキーマを使えば、JSONの内容をマップとして読み取ることができます:
{
"author":"Margaret Atwood",
"title":"The Handmaid's Tale",
"isbn":"978-0099740919"
}
{
"type":"map",
"name":"properties",
"values":"string"
}
その後に次のクエリーを使えば、キーが含まれているエレメントと値が含まれているエレメントを持つレコードの配列を返すことができます:
FROM properties.entry
SELECT {key, value}
これによって次の結果が返されます:
[
{
"key":"author",
"value":"Margaret Atwood"
},
{
"key":"title",
"value":"The Handmaid's Tale"
},
{
"key":"isbn",
"value":"978-0099740919"
}
]