Azure Digital Twins ツイン グラフに対してクエリを実行する
この記事では、クエリの例と、Azure Digital Twins クエリ言語を使用してツイン グラフで情報をクエリする手順について説明します。 (クエリ言語の概要については、クエリ言語に関する記事を参照してください。)
この記事では、デジタル ツインのクエリ言語の構造および共通のクエリ操作を示すサンプル クエリについて説明します。 また、 Azure Digital Twins Query API または SDK を使用してクエリを記述した後にクエリを実行する方法についても説明します。
Note
次のサンプル クエリを、API または SDK の呼び出しで実行している場合は、クエリ テキストを 1 行にまとめる必要があります。
リファレンス ドキュメント
クエリ言語リファレンスは、Azure Digital Twins ドキュメントの左側の目次の「リファレンス」の下にあります。 次のリンクを使用して、リファレンス セクションに直接アクセスすることもできます。
すべてのデジタル ツインを表示する
次に示すのは、インスタンス内のすべてのデジタル ツインの一覧を返す基本的なクエリです。
SELECT * FROM DIGITALTWINS
プロパティで照会
プロパティ (ID とメタデータを含む) を指定してデジタル ツインを取得します。
SELECT *
FROM DIGITALTWINS T
WHERE T.firmwareVersion = '1.1'
AND T.$dtId in ['123', '456']
AND T.Temperature = 70
上記のクエリに示されているように、デジタル ツインの ID は、メタデータ フィールド $dtId
を使用してクエリが実行されます。
ヒント
Cloud Shell を使用して、$
で始まるメタデータ フィールドでクエリを実行する場合は、バックスラッシュで $
をエスケープして、それが変数ではなく、クエリ テキスト内のリテラルとして使用する必要があることを Cloud Shell に通知する必要があります。
特定のプロパティが定義されているかどうかに基づいて Twins を取得することもできます。 次は、Location
プロパティが定義されているツインを取得するクエリです。
SELECT * FROM DIGITALTWINS WHERE IS_DEFINED(Location)
「デジタル ツインにタグを追加する」で説明されているように、このクエリは tag
プロパティを使ってツインを取得する場合に役立ちます。 次は、red
のタグが付いているツインをすべて取得するクエリです。
SELECT * FROM DIGITALTWINS WHERE IS_DEFINED(tags.red)
プロパティの型に基づいてツインを取得することもできます。 次は、Temperature
プロパティが数字であるツインを取得するクエリです。
SELECT * FROM DIGITALTWINS T WHERE IS_NUMBER(T.Temperature)
クエリ マップのプロパティ
プロパティが複合型 Map
の場合は、次のように、マップ キーと値をクエリで直接使用できます。
SELECT * FROM DIGITALTWINS T WHERE T.<propertyName>.<mapKey> = '<mapValue>'
マップ キーが数字で始まる場合は、予約キーワードを使用してクエリを実行する方法と同様に、キーを二重角かっこ ([[<mapKey>]]
) で囲んでクエリでエスケープする必要があります。
モデルでクエリを実行する
IS_OF_MODEL
演算子を使用すると、ツインのIS_OF_MODEL
に基づいてフィルター処理できます。
継承とモデルのバージョン管理が考慮され、指定したツインが次のいずれかの条件を満たしている場合、そのツインに対して true
と評価されます。
-
IS_OF_MODEL()
に指定されたモデルがツインで直接実装されていて、ツインでのモデルのバージョン番号が、指定されたモデルのバージョン番号以上である -
IS_OF_MODEL()
に指定されたモデルを "拡張する" モデルがツインに実装され、ツインの拡張モデルのバージョン番号が、指定されたモデルのバージョン番号 "以上" である。
したがって、たとえば、モデル dtmi:example:widget;4
のツインのクエリを実行した場合、このクエリからは、widget モデルのバージョン 4 以上のに基づくすべてのツインと、widget を継承するすべてのモデルのバージョン 4 以上に基づくツインが返されます。
IS_OF_MODEL
にはいくつかの異なるパラメーターを指定することができます。このセクションの残りの部分では、その各種のオーバーロード オプションのみについて説明します。
IS_OF_MODEL
の最も簡単な使用法では、IS_OF_MODEL(twinTypeName)
のように twinTypeName
パラメーターのみを受け取ります。
このパラメーターで値を渡すクエリの例を次に示します。
SELECT * FROM DIGITALTWINS WHERE IS_OF_MODEL('dtmi:example:thing;1')
(JOIN
が使用されている場合のように) 複数のツイン コレクションがある場合に検索対象を指定するには、IS_OF_MODEL(twinCollection, twinTypeName)
のように twinCollection
パラメーターを追加します。
このパラメーターに値を追加するクエリの例を次に示します。
SELECT * FROM DIGITALTWINS DT WHERE IS_OF_MODEL(DT, 'dtmi:example:thing;1')
完全一致を行うには、IS_OF_MODEL(twinTypeName, exact)
のように exact
パラメーターを追加します。
このパラメーターに値を追加するクエリの例を次に示します。
SELECT * FROM DIGITALTWINS WHERE IS_OF_MODEL('dtmi:example:thing;1', exact)
また、IS_OF_MODEL(twinCollection, twinTypeName, exact)
のように 3 つの引数すべてを渡すこともできます。
3 つのパラメーターすべての値を指定するクエリの例を次に示します。
SELECT * FROM DIGITALTWINS DT WHERE IS_OF_MODEL(DT, 'dtmi:example:thing;1', exact)
リレーションシップによるクエリ
デジタル ツインのリレーションシップに基づいてクエリを実行する場合、Azure Digital Twins クエリ言語には特殊な構文があります。
リレーションシップは FROM
句のクエリ スコープにプルされます。 "従来の" SQL 型言語とは異なり、FROM
句の各式はテーブルではありません。そうではなく、FROM
句は、エンティティ間のリレーションシップのトラバーサルを表します。 リレーションシップをトラバーサルするために、Azure Digital Twins ではカスタム バージョンの JOIN
を使用します。
Azure Digital Twins モデルの機能を使用すると、リレーションシップがツインとは無関係に存在しないことを思い出してください。これは、リレーションシップを個別に照会することができず、ツインに関連付けられている必要があることを意味します。
この事実を反映するために、キーワード RELATED
を JOIN
句に使用して、ツイン コレクションからの特定の種類のリレーションシップのセットを取得します。 次に、クエリでは、WHERE
句でフィルター処理して、リレーションシップ クエリで使用する特定のツインを指定する必要があります (ツインの $dtId
値を使用)。
次のセクションでは、このような例をいくつか示します。
基本的なリレーションシップ クエリ
リレーションシップベースのクエリの例を次に示します。 このコード スニペットによって、ID
プロパティが ABC
であるすべてのデジタル ツインと、contains
リレーションシップを介してこれらのデジタル ツインに関連するすべてのデジタル ツインが選ばれます。
SELECT T, CT
FROM DIGITALTWINS T
JOIN CT RELATED T.contains
WHERE T.$dtId = 'ABC'
リレーションシップの種類 (上の例では contains
) は、リレーションシップの DTDL 定義の name
フィールドを使って示されます。
Note
開発者は、この JOIN
を WHERE
句のキー値と関連付ける (または JOIN
定義を使用してインラインでキー値を指定する) 必要はありません。 リレーションシップのプロパティ自体でターゲット エンティティが識別されるため、この相関関係はシステムによって自動的に計算されます。
リレーションシップのソースまたはターゲットによるクエリ
リレーションシップのクエリ構造を使用すると、リレーションシップのソースまたはターゲットであるデジタル ツインを特定できます。
たとえば、ソース ツインから開始し、そのリレーションシップに従ってリレーションシップのターゲット ツインを見つけることができます。 次に、ツイン source-twin からの feeds
リレーションシップのターゲット ツインを見つけるクエリの例を示します。
SELECT target
FROM DIGITALTWINS source
JOIN target RELATED source.feeds
WHERE source.$dtId = 'source-twin'
また、リレーションシップのターゲットから開始し、リレーションシップをトレースしてソース ツインを見つけることもできます。 次に、ツイン target-twin への feeds
リレーションシップのソース ツインを見つけるクエリの例を示します。
SELECT source
FROM DIGITALTWINS source
JOIN target RELATED source.feeds
WHERE target.$dtId = 'target-twin'
リレーションシップのプロパティのクエリを実行する
デジタル ツインに DTDL を介して記述されるプロパティが存在するのと同様に、リレーションシップにプロパティを含めることもできます。 リレーションシップのプロパティに基づいてツインにクエリを実行できます。
Azure Digital Twins ストア言語を使用すると、JOIN
句内のリレーションシップにエイリアスを割り当てることで、リレーションシップのフィルター処理とプロジェクションを行うことができます。
例として、reportedCondition
プロパティがある servicedBy
リレーションシップを考えてみます。 次のクエリでは、プロパティを参照するために、このリレーションシップに R
という別名が与えられています。
SELECT T, SBT, R
FROM DIGITALTWINS T
JOIN SBT RELATED T.servicedBy R
WHERE T.$dtId = 'ABC'
AND R.reportedCondition = 'clean'
上記の例では、reportedCondition
が servicedBy
リレーションシップ自体のプロパティであることに注意してください (servicedBy
リレーションシップを持つ何らかのデジタル ツインではありません)。
複数の JOIN を使用したクエリ
1 つのクエリで最大 5 つの JOIN
がサポートされているため、複数レベルのリレーションシップを一度に走査できます。
複数レベルのリレーションシップをクエリするには、1 つの FROM
ステートメントに続けて N 個の JOIN
ステートメントを使用します。ここで、JOIN
ステートメントは前の FROM
または JOIN
ステートメントの結果に関するリレーションシップを表します。
次に、複数結合のクエリの例を示します。このクエリでは、ルーム 1 と 2 のライト パネルに含まれるすべての電球が取得されます。
SELECT LightBulb
FROM DIGITALTWINS Room
JOIN LightPanel RELATED Room.contains
JOIN LightBulb RELATED LightPanel.contains
WHERE IS_OF_MODEL(LightPanel, 'dtmi:contoso:com:lightpanel;1')
AND IS_OF_MODEL(LightBulb, 'dtmi:contoso:com:lightbulb ;1')
AND Room.$dtId IN ['room1', 'room2']
項目をカウントする
Select COUNT
句を使用して、結果セット内の項目の数をカウントできます。
SELECT COUNT()
FROM DIGITALTWINS
WHERE
句を追加することで、特定の条件に一致する項目の数をカウントします。 ツイン モデルの種類に基づいて適用されたフィルターを使用してカウントする例をいくつか次に示します (この構文の詳細については、後述する 「モデルでクエリを実行する」 を参照してください)。
SELECT COUNT()
FROM DIGITALTWINS
WHERE IS_OF_MODEL('dtmi:sample:Room;1')
SELECT COUNT()
FROM DIGITALTWINS c
WHERE IS_OF_MODEL('dtmi:sample:Room;1') AND c.Capacity > 20
また、COUNT
を JOIN
句と共に使用することもできます。 次に、ルーム 1 と 2 のライト パネルに含まれるすべての電球をカウントするクエリを示します。
SELECT COUNT()
FROM DIGITALTWINS Room
JOIN LightPanel RELATED Room.contains
JOIN LightBulb RELATED LightPanel.contains
WHERE IS_OF_MODEL(LightPanel, 'dtmi:contoso:com:lightpanel;1')
AND IS_OF_MODEL(LightBulb, 'dtmi:contoso:com:lightbulb;1')
AND Room.$dtId IN ['room1', 'room2']
結果のフィルター処理: 上位項目を選択する
Select TOP
句を使用して、1 つのクエリで複数の "上位" 項目を選択できます。
SELECT TOP (5)
FROM DIGITALTWINS
WHERE ...
結果のフィルター処理: プロジェクションを使用して戻り値のセットを指定する
SELECT
ステートメントでプロジェクションを使用すると、クエリによって返される列を選択できます。 プロジェクションは、プリミティブおよび複合プロパティの両方でサポートされるようになりました。 Azure Digital Twins によるプロジェクションの詳細については、SELECT 句のリファレンス ドキュメントを参照してください。
プロジェクションを使用してツインとリレーションシップを返すクエリの例を次に示します。 次のクエリでは、ID が ABC
の Factory が Factory.customer
のリレーションシップを介して Consumer と関連付けられており、そのリレーションシップが Edge
として表されるシナリオから、Consumer、Factory、Edge がプロジェクションされています。
SELECT Consumer, Factory, Edge
FROM DIGITALTWINS Factory
JOIN Consumer RELATED Factory.customer Edge
WHERE Factory.$dtId = 'ABC'
また、プロジェクションを使用してツインのプロパティを返すこともできます。 以下のクエリでは、"Factory.customer" のリレーションシップを介して、ID が "ABC" の "Factory.customer
" に関連付けられている "ABC
" の "Name
" プロパティがプロジェクションされています。
SELECT Consumer.name
FROM DIGITALTWINS Factory
JOIN Consumer RELATED Factory.customer Edge
WHERE Factory.$dtId = 'ABC'
また、プロジェクションを使用してリレーションシップのプロパティを返すこともできます。 前述の例と同様に、以下のクエリでは、"Factory.customer" のリレーションシップを介して、ID が "ABC" の "Factory.customer
" に関連付けられている "ABC
" の "Name
" プロパティがプロジェクションされていますが、今回は、そのリレーションシップの 2 つのプロパティである prop1
および prop2
も返されます。 これは、リレーションシップに "Edge
" という名前を付け、そのプロパティを収集することで行います。
SELECT Consumer.name, Edge.prop1, Edge.prop2, Factory.area
FROM DIGITALTWINS Factory
JOIN Consumer RELATED Factory.customer Edge
WHERE Factory.$dtId = 'ABC'
また、別名を使用して、プロジェクションによるクエリを簡略化することもできます。
次のクエリを実行すると、前述の例と同じ操作が行われますが、プロパティ名には別名の consumerName
、first
、second
、および factoryArea
が使用されています。
SELECT Consumer.name AS consumerName, Edge.prop1 AS first, Edge.prop2 AS second, Factory.area AS factoryArea
FROM DIGITALTWINS Factory
JOIN Consumer RELATED Factory.customer Edge
WHERE Factory.$dtId = 'ABC'
これは、上記と同じセットに対してクエリを実行する類似のクエリですが、Consumer.name
プロパティのみが consumerName
としてプロジェクションされ、完全な Factory はツインとしてプロジェクションされます。
SELECT Consumer.name AS consumerName, Factory
FROM DIGITALTWINS Factory
JOIN Consumer RELATED Factory.customer Edge
WHERE Factory.$dtId = 'ABC'
IN 演算子を使用して効率的なクエリを作成する
必要なクエリ数を大幅に減らすには、ツインの配列を構築し、IN
演算子を使用してクエリを実行します。
たとえば、"Buildings"(建物) に "Floors" (フロア) が含まれ、"Floors" に "Rooms" (部屋) が含まれるシナリオを考えてみます。 建物内の暑い部屋を見つけるには、1 つの方法として、次の手順に従います。
contains
のリレーションシップに基づいて、建物内のフロアを見つけます。SELECT Floor FROM DIGITALTWINS Building JOIN Floor RELATED Building.contains WHERE Building.$dtId = @buildingId
部屋を見つけるには、フロアを 1 つずつ検討し、
JOIN
クエリを実行してそれぞれの部屋を見つけるのではなく、建物内のフロアのコレクション (以下のクエリでは Floor という名前) を使用してクエリを実行することができます。クライアント アプリ:
var floors = "['floor1','floor2', ..'floorn']";
クエリ:
SELECT Room FROM DIGITALTWINS Floor JOIN Room RELATED Floor.contains WHERE Floor.$dtId IN ['floor1','floor2', ..'floorn'] AND Room. Temperature > 72 AND IS_OF_MODEL(Room, 'dtmi:com:contoso:Room;1')
その他の複合クエリの例
結合演算子を使用して上記のクエリ タイプを組み合わせ、1 つのクエリに含める詳細を増やすことができます。 次に、複数のツイン記述子の種類に対して一度にクエリを実行する複合クエリのその他の例をいくつか挙げます。
- Room 123 に与えられているデバイスの中から、Operator の役割を担う MxChip デバイスが返されます
SELECT device FROM DIGITALTWINS space JOIN device RELATED space.has WHERE space.$dtid = 'Room 123' AND device.$metadata.model = 'dtmi:contoso:com:DigitalTwins:MxChip:3' AND has.role = 'Operator'
- ID が
id1
の別のツインとの間にContains
という名前のリレーションシップがあるツインを取得しますSELECT Room FROM DIGITALTWINS Room JOIN Thermostat RELATED Room.Contains WHERE Thermostat.$dtId = 'id1'
- floor11 によって包含されるこの部屋モデルのすべての部屋を取得します
SELECT Room FROM DIGITALTWINS Floor JOIN Room RELATED Floor.Contains WHERE Floor.$dtId = 'floor11' AND IS_OF_MODEL(Room, 'dtmi:contoso:com:DigitalTwins:Room;1')
API を使用してクエリを実行する
クエリ文字列を決定したら、Query API を呼び出して実行します。
API を直接呼び出すか、Azure Digital Twins で使用可能な SDK のいずれかを使用することができます。
次のコード スニペットは、クライアント アプリからの .NET (C#) SDK 呼び出しを示しています。
// Run a query for all twins
string query = "SELECT * FROM DIGITALTWINS";
AsyncPageable<BasicDigitalTwin> result = client.QueryAsync<BasicDigitalTwin>(query);
この呼び出しで使用されるクエリでは、デジタル ツインの一覧が返されます。これは、上記の例で BasicDigitalTwin オブジェクトによって表されています。 各クエリのデータの戻り値の型は、SELECT
ステートメントで指定する項目によって異なります。
-
SELECT * FROM ...
で始まるクエリでは、デジタル ツイン (BasicDigitalTwin
オブジェクトとして、または独自に作成した他のカスタム デジタル ツインの種類としてシリアル化可能) の一覧が返されます。 -
SELECT <A>, <B>, <C> FROM ...
の形式で始まるクエリでは、キー<A>
、<B>
、<C>
を含むディクショナリが返されます。 - カスタム データを返すように、他の形式の
SELECT
ステートメントを作成できます。 独自のクラスを作成して、カスタマイズされた結果セットが処理されるようにすることを検討してください。
ページングを使用したクエリ
クエリ呼び出しはページングをサポートしています。 エラー処理とページングを含むクエリ結果の種類として BasicDigitalTwin
を使用した完全な例を以下に示します。
AsyncPageable<BasicDigitalTwin> result = client.QueryAsync<BasicDigitalTwin>("Select * From DigitalTwins");
try
{
await foreach (BasicDigitalTwin twin in result)
{
// You can include your own logic to print the result
// The logic below prints the twin's ID and contents
Console.WriteLine($"Twin ID: {twin.Id} \nTwin data");
foreach (KeyValuePair<string, object> kvp in twin.Contents)
{
Console.WriteLine($"{kvp.Key} {kvp.Value}");
}
}
}
catch (RequestFailedException ex)
{
Console.WriteLine($"Error {ex.Status}, {ex.ErrorCode}, {ex.Message}");
throw;
}
次のステップ
この記事のクエリの実行に使用される Query API を含め、詳細については、Azure Digital Twins API と SDK に関する記事を参照してください。