問題定義
Knowledge Graphのエンティティ(ノードとも呼ばれる)はリレーションシップによってリンクされています。エンティティのESRI__ID値は、リレーションシップ列の外部キーであるESRI__OriginIDおよびESRI__DestID に対応しています。ID値はGlobalIDデータ型から派生し、システムによって生成されます。ESRI__ID値はリレーションシップで使用する前にエンティティに存在している必要があるため、多くの人はグラフを2段階で作成または維持する必要があると考えています。つまり、最初にエンティティを作成し、その後リレーションシップを別々に作成し、結果として2つのETLツール、またはエンティティとリレーションシップの組み合わせごとに処理が行われる場合はそれ以上のツールを管理することになります。これは不要です。
このブログでは、エンティティとリレーションシップの両方を書き込む単一のETLツールを使ってグラフを維持する方法を示します。
グラフシナリオ
まずは必須の非常に情報量の多い地図をご覧ください!今日のグラフのテーマは、ETLツール実行時間の前後24時間分の世界中の空港とフライトデータです。したがって、約半数のフライトは過去のもので、残り半数は近い将来に予定されています。フライト経路は実際の航空機ルートをモデル化しているわけではなく、このグラフは接続性のみをモデル化することを目的としています。ユースケースシナリオについては以下をご覧ください。
世界の空港とフライト
ETLツール
データはFlightAwareから提供されており、そのAeroAPIエンドポイントにこのETLツールでアクセスします。このツールはブログダウンロードで入手可能です。ご自身のAPIキーが必要です。
グラフメンテナンス用単一パスETLツール
AeroAPIアクセス権がなくても、ブログ添付ファイルをダウンロードして解凍し、以下のようにコンテンツをインストールしてください(ArcGIS Data Interoperability for Pro 3.5+が必要です):
- Create.fmw - このワークスペースソースファイルをProプロジェクトホームフォルダーに置く
- オプションで、このfmwをソースとしてETLツールを作成可能
- LoopingAirportsGetter.fmx - Create.fmwで使用されるカスタムトランスフォーマー
- ユーザープロファイルフォルダーC:\Users\<yourusername>\Documents\FME\Transformersに配置すること
ツールには多くの有用な資料がありますが、ブログの主な目的である「単一ワークスペースでエンティティとリレーションシップを書き込む方法」にすぐに到達するために、Create.fmwでは最初にFeatureWriterトランスフォーマーでエンティティを書き込み、その後FeatureWriterのSummary出力ポートを使ってFeatureReaderトランスフォーマーでエンティティを再読み込みしています。これにより必要なESRI__ID値が得られます。ワークスペースはこの順序を示すためにコンパクトには配置されていませんが、空港を書き込むFeatureWriterという名前のトランスフォーマーから、そのSummaryポートが空港を読み込むFeatureReaderトランスフォーマーへ直接接続されていることがわかります。Summaryポートは書き込みトランザクション完了後に識別情報や統計プロパティを持つ単一非空間フィーチャーを出力します。
リレーションシップの書き込みは下流依存関係がないため、通常のEsri Knowledge Graphライターで行うことができます。本日ここまで読んだだけならこれ以上読む必要はありませんが、ETLへの深い理解がお好きなら残りの記事も学びになるでしょうのでぜひお読みください!
私はAPIから取得したデータでグラフを作成しています。このAPIは標準的な最新プラクティスに従っており、RESTコールはページネーションされたJSONレスポンスを返し、API全体にはOpenAPI仕様があります。APIはこちらのURLで確認でき、OpenAPI仕様書へのリンクもあります。
OpenAPI仕様書が利用可能なので、それをOpenAPICallerトランスフォーマーにインポートできます。これによりHTTPコール構築がフォーム入力作業になります。ワークスペース内最初のOpenAPICallerをご覧ください。100ページ(1500レコード)の空港データ要求とヘッダーにはAPIキー用ツールパラメーターとJSONレスポンス受信要求が含まれています。空港スキーマは幅広くないため1500レコードでもHTTP GETレスポンス過負荷やエラーにはなりませんが、これは初期レコードセットのみ取得しており全空港データではありません。
空港用OpenAPICaller
APIはページネーションをサポートしています。もしリクエストがサーバー上で利用可能な最後のレコードまで返さない場合、レスポンス内にnext(URL)というJSONオブジェクトがあり、それをリクエストとして送信すると次ページセットが返されます。これによりすべてのデータ取得ループ処理が可能となり、それがカスタムトランスフォーマーLoopingAirportsGetterによって実装されています。
LoopingAirportsGetter
次URLは自動生成されるため、このカスタムトランスフォーマー内では別途OpenAPICallerではなく単純なHTTPCallerを使用できます。これで全空港データが揃い、エンティティタイプを書き出せます。
ツールを見ると、空港エンティティを書き込んだ後、それらが(ESRI__ID値付きで)再読み込みされ、その後別のOpenAPICallerによって各空港ごとのフライト情報が取得されていることがわかります。今回は50ページ分(スキーマ幅広いため)のデータを呼び出しごとに取得しますが、大規模カーソルでページングする代わりに各空港ごとのフライト情報なので最大25コールまで同時実行可能です。
フライト用OpenAPICaller
48時間以内に50ページ(750レコード)以上ある世界中数か所の空港については、HTTPCallerによってnext は初期リクエストからnullではありません。<\/P>
start<\/STRONG>およびend<\/STRONG>クエリパラメータに注意してください。これらはISO形式のUTCタイムスタンプで、ツール起動時にスクリプト化されたパラメータによって生成されます - つまり、私のETLツールにいくつかのコードが入り込んでいます!これはtransformersで実行することも可能です。<\/P>ArcGISにおけるGraph<\/H4> <\/P>エンティティとリレーションシップ構築ロジックを調べるためにツールを自由に操作してもらいますが、基本的にエンティティタイプはAirports<\/STRONG>(ポイント)とFlights<\/STRONG>(2点間のライン)であり、リレーションシップは空港がフライトの出発を持つ(HasDeparture<\/STRONG>)、フライトが他のフライトへの接続を持つ可能性がある(HasConnection<\/STRONG>)、そしてフライトが空港への到着を持つ(HasArrival<\/STRONG>)というものです。接続に使用されるビジネスロジックは、到着便が出発便の1時間から4時間前の間に着陸した場合にフライトが接続されるというものです。実際にはコードシェアの合意など他の要因もあるかもしれませんが、これは単なるデモです!<\/P>こちらがグラフデータモデルビューで、空港とフライトがお互いにリレーションシップを持ち、フライト同士も接続関係があります。Documentエンティティは使用されていません。<\/P>
FlightAware Graph Data Model<\/span><\/span><\/P>さて、分析クエリを作成しましょう!私は法執行官で、ロサンゼルスからベルリンへ向かったか、または向かおうとしている疑わしい宝石泥棒について、航空会社や空港に乗客名簿や最近の映像を確認してほしいと考えています。どの航空会社、フライト、空港に問い合わせるのが最も理にかなっているでしょうか?もちろん私はopenCypher<\/A>のスキルを駆使し、日々更新されるgraphを使います!<\/P>コードを順に見てもらいますが、このクエリはロサンゼルスとベルリン・ブランデンブルク間の最短飛行時間経路を最大4区間まで見つけます。<\/P>
match path = (origin:Airports)-[:HasDeparture|:HasConnection*0..3]->(:Flights)-[:HasArrival]->(destination:Airports)
ディスカッション<\/H4> <\/P>これは単一ツールアプローチとAPIデータおよびKnowledge Graphs活用について多くを示しています。<\/STRONG>ダウンロード内のETLワークスペースはAPIキーを持ち既にgraphを構築済みであればすぐに実行可能な状態です。ツールはArcGIS Proの通常のツールスケジューリング機能で毎日など定期的に実行できます。最初はこの状態にはありませんが、一部手動でツールを実行するためにCreator transformersなどを見ることができ、例えばAirportsエンティティ作成用などです。不要なストリーム内のCreatorsや他のtransformersを一時的に無効化してこの方法で作業します。Knowledgeはリレーションシップの起点と終点指定をサポートしているので(データモデル表示用)、空のリレーションシップは手動で作成しました。<\/P>質問や感想があればこの投稿にコメントしてください。graph ETLを楽しんでください!<\/P>