注: 以下の翻訳の正確性は検証されていません。AIPを利用して英語版の原文から機械的に翻訳されたものです。
クエリエディター を使用すると、データソースをクエリできます。データソースの種類によって、クエリエディターで異なるクエリを書くことができます。以下では、さまざまなタイプのクエリの書き方と例について、それぞれのタイプのクエリで Handlebars を使用する際のセキュリティ上の注意点、クエリパーシャルと条件付きクエリの紹介を提供しています。
Foundry のクエリ は、Foundry Synchronizer を使用し、すべての同期されたテーブルに対して読み取り専用の権限を強制します。また、Foundry のデータセットレベルで付与されたアクセス権に従って、個々のテーブルへのアクセスが制御されます。
Foundry の外部のデータソースについては、クエリで Handlebars を使用すると、悪意のあるユーザーがテンプレートの内容を有害なコードに置き換えてインジェクション攻撃を行う可能性があるため、セキュリティ上の懸念が生じます。このため、これらのクエリでは Handlebars の使用に関して追加のセキュリティルールが必要となります。詳細なルールは、以下の SQL クエリ と HTTP JSON クエリ のセクションで説明されています。
また、ユーザー変数 (例: {{user.firstName}}
) を参照するテンプレートは、ブラウザのログイン時に渡された値ではなく、サーバーから値を取得します。
SQL セキュリティエラーの例:
HTTP JSON セキュリティエラーの例:
Slate で Foundry からデータをクエリする際には、Foundry Synchronizer を使用することが推奨されています。このセットアップでは、Foundry 内に Postgres インスタンスが提供され、Foundry Synchronizer を使用して SQL テーブルとして利用可能になった Foundry データセットから通常の SQL クエリを書いてデータを取得することができます。
SQL セキュリティヘルパーを使用する必要はありません。
Foundry Synchronizer は、Foundry Synchronizer のドキュメント内の同期 UI セクションで言及されている Metadata View から操作することも、Slate で直接データセットを追加して Slate 内の Datasets タブから Foundry Synchronizer とやりとりすることもできます。Foundry データソースが Slate に追加されると、Datasets タブが自動的に有効になります。UI を操作するには、Datasets パネルで Slate にデータセットを追加し、Sync to Postgres セクションを確認してください。
適用して同期 ボタンをクリックします。
同期が完了すると、Datasets タブ内の Postgres パネルに、Slate のクエリタブに貼り付けるための SQL クエリ例が表示されます。リミットは、誤って期待よりも多くのデータをクエリすることを防ぐために含まれています。Slate での実際のクエリでは、この制限を削除することができます。インデックスの作成やテーブル名のカスタマイズなどの操作については、同期 UI ドキュメント自体を参照して、UI を通じて Foundry Synchronizer とやりとりする方法を確認してください。
オブジェクトタイプをバックアップする Phonograph テーブルをクエリする場合、オブジェクトセット を使用して、オブジェクトをフィルター処理し、集計し、並べ替えることを検討してください。
Phonograph は、データソースタイプで、Foundry データと同期された Phonograph サービスとやりとりし、Foundry データセットへのクエリと変更の書き込みを行う ElasticSearch バックエンドの API を提供します。
Slate からこのサービスを使用する詳細な手順については、Slate から Foundry にデータを書き戻す を参照してください。
SQL クエリ内のすべての Handlebars テンプレート (Foundry データソースを使用するものを除く) は、SQL セキュリティヘルパーまたは Handlebars 組み込みヘルパー によって囲まれている必要があります。SQL ヘルパー で、各 SQL セキュリティヘルパーをいつ、どのように使用するかの詳細を確認できます。
5 つのヘルパーがあり、それらは schema、table、column、alias、および param です。
schema
、table
: schema
および table
ヘルパーは非常に類似しています。名前と許可された名前のリストが与えられると、ヘルパーはその名前が許可された名前のリストに存在し、対応する情報スキーマテーブルに存在することを確認します。たとえば、テーブルヘルパーは、テーブル名が許可された名前のリストとデータベース内の information_schema.tables
または対応するスキーマテーブルに存在するかどうかをチェックします。許可された名前のリストを指定することで、クエリがアクセスすべきでないスキーマ/テーブルにアクセスすることを防ぎます。許可された名前をテンプレート化することはできません。これは、検証の目的を無効にするためです。Copied!1 2
-- 以下のコードは、指定したスキーマ(許可されたスキーマ名1または許可されたスキーマ名2)とテーブル(許可されたテーブル名1)からcolumn1を選択します。 SELECT column1 FROM {{schema someSchemaName 'allowedSchemaName1' 'allowedSchemaName2'}}.{{table someTableName 'allowedTableName1'}};
column
: column
ヘルパーは、名前が information_schema.columns
またはデータベース内の対応するスキーマテーブルに存在することを確認します。Copied!1 2
-- 以下のSQLクエリは、table1からsomeColumnName列を選択します SELECT {{column someColumnName}} FROM table1;
alias
: alias
ヘルパーは、エイリアスのスキーマ、テーブル、または行名をテンプレート化したい場合に使用します。エイリアス名は情報スキーマにないため、Slate で alias
ヘルパーを使用して登録する必要があります。そうしないと、その名前は検証できません。alias
ヘルパーは、定数文字列でのみ使用でき、参照では使用できません。つまり、{{alias 'someConstantString'}}
は許可されていますが、{{alias someReference}}
は許可されていません。それをテンプレート化すると、schema
、table
、または 行
での検証の目的が失われてしまいます。なぜなら、それらは同じものを参照できるからです。Copied!1 2 3 4 5 6 7
SELECT column1 as {{alias 'aliasedColumnName'}} -- column1を'aliasedColumnName'というエイリアス名で選択します FROM table1 -- table1からデータを取得します ORDER BY {{column someColumnName}} -- someColumnNameによって順序付けられます where someColumnName is 'aliasedColumnName' and 'aliasedColumnName' is not a valid column name in the database's schema. -- someColumnNameが'aliasedColumnName'である場合と、'aliasedColumnName'がデータベースのスキーマの有効なカラム名でない場合
param
: param
ヘルパーは、テンプレートを「?」に置き換えることで、後でpreparedStatement
を使用して値を設定できるようにします。PreparedStatementは、SQLインジェクションに対する保護のための最も安全な方法の1つです。フロントエンドからのすべての値は数字または文字列であることに注意してください。したがって、クエリで数字や文字列以外の型を使用するには、その型に値をキャストする必要があります。Copied!1 2 3 4 5 6
-- 以下のSQLコードは、特定の条件を満たすレコードを抽出します。 -- {{param value1}}よりも大きな値を持つ'column1'のレコードと、 -- {{param value2}}より前の日付を持つ'dateColumn1'のレコードを選択します。 SELECT column1 FROM table1 WHERE column1 > {{param value1}} and dateColumn1 < {{param value2}}::date
schema
、table
、または column
ヘルパーのいずれかを使用してください。alias
ヘルパーでエイリアスを登録してください。param
ヘルパーを使用してください。SQL データソースをクエリする場合、エディタはどのような SQL コマンドでも受け入れます。通常、SELECT ステートメントを実行します。例:
Copied!1 2
-- 名前、直径、周期をallNamedから選択します SELECT name,diameter,period FROM allNamed;
Slate は、結果として得られる行を JSON に解析し、各行のキーを作成することで、ハンドルバー経由でアクセスできるようにしています。
Copied!1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
{ // 名前 "name": [ "Undina", "Hekate" ], // 直径 (単位: キロメートル) "diameter": [ 126.42, 88.66 ], // 周期 (単位: 地球日) "period": [ 5.68801089633658, 5.42957878301233 ] }
データ変換は、SQL の組み込み関数を使用して、基本的な文字列や数学演算を実行できます。
すべての HTTP JSON クエリは、以下の条件を満たす必要があります。
jsonStringify
ヘルパーは、テンプレートの値が現在のスコープから脱出できないことを保証します。たとえば、ブロックを閉じてリクエストに追加のプロパティを追加することはできません。Copied!1 2 3 4 5 6 7 8 9 10 11 12 13
{ "path": "path/to/api", // APIへのパス "method": "POST", // 使用するHTTPメソッド "bodyJson": { "filter": {{jsonStringify w1.text}} // フィルターとして使用するJSON文字列 }, "extractors": { "result": "$" // 結果を抽出するためのパス }, "headers": { "Custom_Header": "my custom header value" // カスタムヘッダーの値 } }
プロパティの一部としてテンプレートを使用する例:
Copied!1 2 3 4 5 6 7 8 9 10 11 12 13
{ "path": "path/to/api", // APIへのパス "method": "POST", // 使用するHTTPメソッド "bodyJson": { "filter": {{#jsonStringify}}some text plus {{w1.text}}{{/jsonStringify}} // フィルタパラメータ、テキストと変数w1.textを組み合わせてJSON文字列化 }, "extractors": { "result": "$" // 結果を抽出するためのパス }, "headers": { "Custom_Header": "my custom header value" // カスタムヘッダー } }
..
はパスに使用できません。これにより、クエリパスが親スコープをインデックス化せず、アクセスすべきでない情報にアクセスしないことが確保されます。HTTP JSON データソースのクエリは、以下のプロパティを含むオブジェクトです: path
, method
, bodyJson
, extractors
。
path
: データソースへのURLパスqueryParams
: (オプション) リクエストを構築する際にURLに追加するキーと値のペアのマップ (つまり、"クエリ": "何か" は ?query=something を path
に追加します)。このマップが空でない場合、クエリパラメーターは path
に指定すべきではありません。method
: リクエストを行うために使用されるHTTPメソッド。サポートされているメソッドは GET、POST、DELETE、PUT です。bodyJson
: (オプション) APIエンドポイントへデータとして送信されるJSON (例: データの形式や集約の方法)。あなたのデータソースエンドポイントがJSONを期待していない場合、このフィールドは必要ありません。extractors
: クエリが返す結果。何を抽出するかを決定するために JSONPath を使用します。例えば、全結果を見るには "result": "$"
を使用します。JSONPathの書き方については、以下の tester を参照してください。JSONPathに関する詳細情報は、JSONPath examples をご覧ください。headers
: (オプション) リクエストに設定するヘッダーのマップ。認証ヘッダーが存在する場合、このリストの上に追加されます。Copied!1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
{ "path": "astronomy/_comets", // パス:天文学/彗星 "queryParams": { "limit": 5, // クエリパラメータ:取得件数の制限は5件 "text": "searchabc" // クエリパラメータ:テキスト検索キーワードは "searchabc" }, "method": "GET", // メソッド:GET "bodyJson": { "fields" : ["name", "type", "date"], // ボディJSON:フィールドは「名前」「タイプ」「日付」 "query": { "type": "dust" // クエリ:タイプは "dust" } }, "extractors": { "name": "$.results[*].fields.name" // エクストラクタ:nameフィールドの取り出し方 }, "headers": { "Custom_Header": "my custom header value" // ヘッダー:カスタムヘッダーの値 } }
以下は、Elasticsearch を使用した例です。
Copied!1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
{ "path": "geologist/_search", // 検索パスを指定します "method": "POST", // HTTPメソッドを指定します、ここではPOSTを使用します "bodyJson": { // リクエストボディのJSON "query": { // クエリ部分 "prefix": { // プレフィクスクエリ "request": "/daily/api/permalinks/" // "request"フィールドがこのプレフィクスで始まるドキュメントを検索します } }, "aggs": { // 集約部分 "views": { // 集約の名前 "terms": { // 項目集約 "field": "auth", // "auth"フィールドについて集約します "size": 0 // 集約サイズを0に設定します } } } }, "extractors": { // エクストラクタ部分(結果から特定の情報を抽出します) "Users": "$.aggregations.views.buckets[*].key", // ユーザーのキー情報を抽出します "Views": "$.aggregations.views.buckets[*].doc_count" // ビューのドキュメント数を抽出します } }
Elasticsearch の詳細については、Query DSL documentation をご覧ください。
SERVICEAPI
データソースタイプは、Slate 開発者向けに公開 API を利用可能にした Foundry サービスに特化しています。利用可能なサービスは Foundry インスタンスによって異なりますが、一般的には Build サービス、Compass、または Catalog サービスが含まれます。
各サービス API が追加されると、API のドキュメントがインラインで表示されます。リクエスト入力の隣にある Show Details トグルを開くことで、ペイロードタイプの具体的な例が見つかることがよくあります。これらのエンドポイントは、単純な HTTPJSON
データソースタイプのクエリとは異なる方法でセキュリティが確保されているため、ハンドルバー入力に {{jsonstringify}}
を使用する必要はありません。
アプリケーションに Foundry インテグレーションを開発したい場合は、Palantir の担当者にお問い合わせください。
クエリパーシャルを使用すると、ドキュメント内の複数のクエリで再利用できるクエリコードを記述できます。パーシャルを作成するには、クエリエディタパネルで + New Partial ボタンをクリックします。
パーシャルをクエリに挿入するには、{{>partialName}}
と記述します。例えば、columnFilter
という名前のパーシャルがあり、その内容が WHERE column={{param w8.selectedValue}}
であるとします。その場合、SELECT * from table {{>columnFilter}}
というコードを持つ別のクエリを作成できます。これは、クエリ SELECT * from table WHERE column={{param w8.selectedValue}}
にレンダリングされます。
また、パーシャルに引数を渡すこともできます。構文は {{>partialName
arg1=value1 arg2=value2 arg3=value3}}
です。パーシャルのコンテキスト内の引数の値は、特定のクエリで提供する値に置き換えられます。値は、静的な値(文字列や数値など)や Handlebars の参照(w8.selectedValue
など)を使用できます。上記の例では、2つの異なる選択された値でフィルター処理される2つのクエリがまったく同じである場合、columnFilter
を WHERE column={{param columnValue}}
に再定義し、クエリを SELECT * from table {{>columnFilter columnValue=w8.selectedValue}}
にすることができます。これは、以前と同様に SELECT * from table WHERE column={{param w8.selectedValue}}
としてレンダリングされます。
パーシャルをネストすることもでき、コードの再利用がさらに可能になります。
パーシャルは Handlebars の概念であり、Slate の実装では Handlebars の構文を使用しています。詳細については、Handlebars partials documentation を参照してください。
クエリ設定パネルを使用すると、クエリが実行される条件を制御できます。クエリを条件付きで実行するには、2つのオプションがあります。「すべての依存関係が null でない場合」を選択すると、クエリ内のすべての単一ハンドルバー参照が null でない場合にのみ実行されます。また、「これが true を返す場合にのみ実行する」を選択すると、ハンドルバーコンディションを指定できます。この条件は、関数やウィジェットプロパティなど、クエリが実行できるロジックを制御するために使用したいものにすることができます。このハンドルバー参照が true に評価される場合にのみクエリが実行されます。そうでない場合、クエリは実行されません。
次のクエリは、w_visits_bar.selection.data
から少なくとも1つの値が必要です。
値が存在しない場合、Postgres へのリクエストは構文エラーで失敗します。
すべての依存関係が null でない場合にのみ実行する条件を追加すると、Postgres に接続やリソースを消費する悪いリクエストが送信されるのを防ぐことができます。
次のクエリは、タブ付きコンテナ内のウィジェットに表示するためのデータを取得します。このウィジェットはページの読み込み時には表示されず、ページレベルのフィルターに依存しています。この場合、ウィジェットが表示されているときにのみクエリを実行する条件を追加することを検討してください。これは、クエリ設定で「これが true を返す場合にのみ実行する」オプションを使用して行うことができます。
Slate の Platform タブで Object Set Builder を使用してデータをロードすることができる場合は、できるだけそれを使用してください。Object Set Builder を使用すると、オントロジーを簡単にクエリでき、以下の例に示すような表形式のデータが返されます。以下で説明する Postgres ワークフローは、レガシーな使用法を参照するために残されています。
以下の手順に従って新しいデータを同期する前に、Projects & files の左サイドバーにある Projects ビューを通じて、Foundry Training and Resources Project
が利用可能であることを確認してください。
プロジェクトが利用可能であれば、以下の手順に従い、Ontology Project: Aviation フォルダーの Foundry Reference Project から flights
および airports
データセットを新しいアプリケーションに追加します。残りのチュートリアル手順では、last-mile-flights
の代わりに flights
データセットを使用してください。
Foundry Reference Project の flights
および airports
データセットには、すでに同期が設定されているはずです。これらのデータセットを使用している場合は、以下の関連する指示セクションをスキップできます。
Foundry Reference プロジェクトから既存の flights
および airports
データセットを使用していない場合は、アップロードした last-mile-flights
および airports
データセットを Foundry で使用できるようにする必要があります。Datasets パネルを開き、+Add を選択して Foundry リソースセレクターを開きます。
リソースセレクターで All Files > Getting started data を選択するか、リソースセレクターの検索ボックスを使用して last-mile-flights
データセットに移動します。データセットが見つかったら、インポート設定を開始するために Select last-mile-flights オプションを選択します。
設定オプションを表示するには、Sync to Postgres の隣にある矢印を選択します。
Postgres のデフォルトのテーブル名は、ファイルパスと大文字/小文字が混在したデータセット名を含みます。特殊文字 /
、大文字、およびスペースを扱うために、Postgres はテーブル名を引用符で囲んだ識別子として扱います。これは、クエリでテーブルを参照するたびに、二重引用符を含めなければ Postgres が構文エラーをスローすることを意味します。セットアップで Postgresql table name
を含め、スネークケースで小文字と _
を使用して二重引用符の使用を回避することをお勧めします。
まだデータアクセスパターンが定義されておらず、last-mile-flights
データセットは比較的小さいため、テーブルにインデックスを作成しません。後で追加することができます。Apply and sync を選択して同期を開始します。Check Status ボタンを使って同期を監視できます。
同期が完了すると、Slate で使用するためのサンプルクエリが表示されます。ただし、データセット名に付加された番号は異なります。
Copied!1 2
-- "foundry_sync"."Getting Started Data/last-mile-flights-master-9406" から全てのデータを選択し、結果の最初の10行だけを表示します。 SELECT * FROM "foundry_sync"."Getting Started Data/last-mile-flights-master-9406" LIMIT 10
アプリケーションの構築に役立てるため、クエリをコピーして後で使用します。次に、airports
データセットを Slate と同期します。
まず、同期したデータセットから必要なデータを取得するための SQL クエリを作成します。
Queries を選択してエディタを開きます。
Queries リスト、Partials リスト、そしてエディタが表示されるはずです。まだクエリが作成されていないため、これらのリストは空です。 + 新規クエリ を選択します。エディタには、ツールバー、テキストエディタ、クエリ結果のプレビューパネルが表示されるはずです。
名前 テキストボックスに、クエリ名として q_allFlights
を入力します。ソース ドロップダウンから FOUNDRY
タイプのデータソースを選択し、Slate をデータベースに向けます。このデータソースは foundry-sync
、foundry-postgate
、foundry
などと呼ばれることがありますが、必ずデータソース名の右側に FOUNDRY
タイプが表示されます。
クエリを q_
のようなクエリ識別子で始めるように命名することをお勧めします。これは、大規模で複雑なアプリケーションを構築する際に特に役立つベストプラクティスです。
このクエリでは、データベースの last-mile-flights
テーブルからいくつかの行データを取得したいと考えています。これを行うには、先ほどエディタにコピーしたサンプルクエリを使用できます:
Copied!1 2
-- "foundry_sync"."Getting Started Data/last-mile-flights-master-9406" から全てのデータを選択し、結果の上位10件を取得します。 SELECT * FROM "foundry_sync"."Getting Started Data/last-mile-flights-master-9406" LIMIT 10
以下で使用する例のクエリでは、特定のテーブル名の代わりに "variable" を使用します。例えば、"foundry_sync"."Getting started data/last-mile-flights-master-9406"
ではなく、"foundry_sync"."{{v_flightTable}}"
と表示されます。
クエリが機能するかどうかを確認するには、Test を選択するか、Windows で Ctrl+Enter
、macOS で Cmd+Enter
を使用します。これにより、クエリの結果が Preview パネルに表示されます。
エラーが発生した場合は、Slate で last-mile-flights
を利用可能にしていることと、正しいパスを使用していることを確認してください。
Update Query を選択してクエリを保存します。
< / > を選択することで、生の JSON レスポンス構造で結果を表示することができます。
データセットには多くの行があるため、興味のあるいくつかの行だけを取得するようにクエリを絞り込みます。
Copied!1 2 3 4 5 6 7 8 9 10 11 12
SELECT flight_id, -- フライトID carrier_code, -- キャリアコード tail_num, -- 尾部番号 origin, -- 出発地 dest, -- 目的地 dep_ts_utc, -- UTCでの出発時間 arr_ts_utc, -- UTCでの到着時間 distance, -- 距離 actual_elapsed_time -- 実際の経過時間 FROM "foundry_sync"."{{v_flightTable}}" -- "foundry_sync"スキーマの"v_flightTable"という名前のテーブルからデータを取得します LIMIT 10 -- 結果の最初の10行だけを取得します