困りごと
BigQueryでSQLを使用してテーブルからデータを取得する際、BigQuery APIを使用するとJSONで結果を取得することができる。
しかし、JavaのクライアントライブラリでSQLの結果を取得した場合、FieldValueのAttributeにRECORDとREPEATEDが混じっていると構造が複雑になり、すんなりとJSONには変換できない。
動作確認環境
- Kotlin: 1.6.10
- Google Cloud BigQuery Client for Java: 1.100.0
解決方法
BigQueryのSQLでTO_JSON_STRING関数を使用すれば結果がJSON文字列で取得できることを利用する。
SELECT
TO_JSON_STRING(result) AS json
FROM (
SELECT
*
FROM
`$projectId.$datasetName.$tableName`
) AS result
;
import com.fasterxml.jackson.core.type.TypeReference
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.google.cloud.bigquery.BigQueryOptions
import com.google.cloud.bigquery.QueryJobConfiguration
fun query(): String {
val projectId = "MY_PROJECT_ID"
val datasetName = "MY_DATASET_NAME"
val tableName = "MY_TABLE_NAME"
val query = "SELECT TO_JSON_STRING(result) AS json FROM (SELECT * FROM `$projectId.$datasetName.$tableName`) AS result"
val bigQuery = BigQueryOptions.getDefaultInstance().service
val queryConfig = QueryJobConfiguration.of(query)
val results = bigQuery.query(queryConfig)
val mapper = jacksonObjectMapper()
// 一度オブジェクトに変換する
val resultList = results.iterateAll().map { row ->
val jsonString = row.get("json").stringValue
mapper.readValue<Any>(
jsonString,
object: TypeReference<Any>() {}
)
}
// JSON文字列として出力する
return mapper.writeValueAsString(resultList)
}