Kusto 照会言語 (KQL) グラフ セマンティクスを使用する一般的なシナリオは何ですか?
Kusto 照会言語 (KQL) のグラフ セマンティクスを使用すると、データをグラフとしてモデル化し、クエリを実行できます。 グラフは、ソーシャル ネットワーク、レコメンデーション システム、接続された資産、ナレッジ グラフなど、多対多、階層的、またはネットワーク化されたリレーションシップを含む複雑で動的なデータを表すのに役立つ多くのシナリオがあります。
この記事では、KQL グラフ セマンティクスを使用するための次の一般的なシナリオについて説明します。
友人の友人
グラフの一般的なユース ケースの 1 つは、ノードがユーザーであり、エッジがフレンドシップまたは相互作用であるソーシャル ネットワークをモデル化してクエリすることです。 たとえば、 Users という名前や組織などのユーザーに関するデータを含むテーブルと、次の図に示すようにユーザー間のフレンドシップに関するデータを含む Knows というテーブルがあるとします。
KQL でグラフ セマンティクスを使用しない場合は、次のように複数の結合を使用して、友人のフレンドを検索するグラフを作成できます。
let Users = datatable (UserId: string, name: string, org: string)[]; // nodes
let Knows = datatable (FirstUser: string, SecondUser: string)[]; // edges
Users
| where org == "Contoso"
| join kind=inner (Knows) on $left.UserId == $right.FirstUser
| join kind=innerunique(Users) on $left.SecondUser == $right.UserId
| join kind=inner (Knows) on $left.SecondUser == $right.FirstUser
| join kind=innerunique(Users) on $left.SecondUser1 == $right.UserId
| where UserId != UserId1
| project name, name1, name2
KQL でグラフ セマンティクスを使用すると、より直感的で効率的な方法で同じクエリを実行できます。 次のクエリでは、 make-graph 演算子 を使用して、 FirstUser から SecondUser への有向グラフを作成し、 Users テーブルによって提供される列を使用してノードのプロパティを強化します。 グラフがインスタンス化されると、 graph-match 演算子 は、フィルターやプロジェクションを含むフレンドオブフレンド パターンを提供し、結果として表形式の出力になります。
let Users = datatable (UserId:string , name:string , org:string)[]; // nodes
let Knows = datatable (FirstUser:string , SecondUser:string)[]; // edges
Knows
| make-graph FirstUser --> SecondUser with Users on UserId
| graph-match (user)-->(middle_man)-->(friendOfAFriend)
where user.org == "Contoso" and user.UserId != friendOfAFriend.UserId
project contoso_person = user.name, middle_man = middle_man.name, kusto_friend_of_friend = friendOfAFriend.name
ログ データからの分析情報
一部のユース ケースでは、ログ データなどの時系列情報を含む単純なフラット テーブルから分析情報を取得する必要があります。 各行のデータは、生データを含む文字列です。 このデータからグラフを作成するには、まず、グラフ分析に関連するエンティティとリレーションシップを特定する必要があります。 たとえば、タイムスタンプ、送信元 IP アドレス、宛先リソースなどの要求に関する情報を含む web サーバーから rawLogs というテーブルがあるとします。
次の表に、生データの例を示します。
let rawLogs = datatable (rawLog: string) [
"31.56.96.51 - - [2019-01-22 03:54:16 +0330] \"GET /product/27 HTTP/1.1\" 200 5379 \"https://www.contoso.com/m/filter/b113\" \"some client\" \"-\"",
"31.56.96.51 - - [2019-01-22 03:55:17 +0330] \"GET /product/42 HTTP/1.1\" 200 5667 \"https://www.contoso.com/m/filter/b113\" \"some client\" \"-\"",
"54.36.149.41 - - [2019-01-22 03:56:14 +0330] \"GET /product/27 HTTP/1.1\" 200 30577 \"-\" \"some client\" \"-\""
];
この表のグラフをモデル化する方法の 1 つは、ソース IP アドレスをノードとして扱い、リソースへの Web 要求をエッジとして扱うことです。 parse 演算子を使用してグラフに必要な列を抽出し、さまざまなソースと宛先間のネットワーク トラフィックと相互作用を表すグラフを作成できます。 グラフを作成するには、 make-graph 演算子を使用し ソース列と変換先列をエッジ エンドポイントとして指定し、必要に応じて追加の列をエッジまたはノードのプロパティとして指定できます。
次のクエリでは、生ログからグラフが作成されます。
let parsedLogs = rawLogs
| parse rawLog with ipAddress: string " - - [" timestamp: datetime "] \"" httpVerb: string " " resource: string " " *
| project-away rawLog;
let edges = parsedLogs;
let nodes =
union
(parsedLogs
| distinct ipAddress
| project nodeId = ipAddress, label = "IP address"),
(parsedLogs | distinct resource | project nodeId = resource, label = "resource");
let graph = edges
| make-graph ipAddress --> resource with nodes on nodeId;
このクエリでは、生ログを解析し、ノードが IP アドレスまたはリソースのいずれかであり、各エッジがソースから宛先への要求であり、タイムスタンプと HTTP 動詞がエッジ プロパティである有向グラフを作成します。
グラフが作成されたら、 graph-match 演算子 を使用して、パターン、フィルター、プロジェクションを使用してグラフ データにクエリを実行できます。 たとえば、次のように、過去 5 分以内に他の IP アドレスが要求したリソースに基づいて簡単な推奨事項を作成するパターンを作成できます。
graph
| graph-match (startIp)-[request]->(resource)<--(otherIP)-[otherRequest]->(otherResource)
where startIp.label == "IP address" and //start with an IP address
resource.nodeId != otherResource.nodeId and //recommending a different resource
startIp.nodeId != otherIP.nodeId and //only other IP addresses are interesting
(request.timestamp - otherRequest.timestamp < 5m) //filter on recommendations based on the last 5 minutes
project Recommendation=otherResource.nodeId
出力
推奨 |
---|
/product/42 |
このクエリは、生のテキスト ベースのログに基づいて、推奨事項として "/product/42" を返します。