インデックス付きプロパティ
ThingWorx 9.3 以降では、迅速なクエリーを可能にするために、プロパティをインデックシングできます。頻繁に変更されないプロパティのみをインデックシングする必要があります。たとえば、モデル番号、シリアル番号、都市、地域などです。ThingWorx でインデックシングされた場合、プロパティ値はプロパティ永続化プロバイダに保存され、QueryImplementingThingsOptimized および QueryImplementingThingsOptimizedCount API を使用する際により迅速なクエリーが可能になるようにデータベースによってインデックシングされます。
クエリーにインデックス付きプロパティのみが含まれている場合、クエリーはデータベースクエリーとしてのみ実行されます。
クエリーにインデックス付きプロパティとインデックスなしプロパティの両方が含まれている場合、ThingWorx はインデックスクエリーを実行することによる利点があるかどうかを調べてから実行します。このシナリオでは、ThingWorx は最初に、フィールドがインデックシングされているプロパティデータベースからインデックスクエリーを実行します。結果セットが生成されると、ThingWorx はメモリ内キャッシュに対してインデックスなしプロパティのクエリーを実行します。この例として、気温 (テレメトリデータ - インデックシング不可能) が一定のしきい値を超える特定の都市 (インデックス付きプロパティ) に存在するすべての Thing をクエリーする場合があります。ThingWorx は最初にデータベースから都市のクエリーを実行してから、メモリ内キャッシュ上のテレメトリデータ (気温) に対してクエリーを実行します。
リクエストされたクエリーがインデックシングによる利点を得られない場合、ThingWorx はメモリ内キャッシュに対してクエリーを実行します。
ほとんどの場合、データベースに対してクエリーを実行することで優れたパフォーマンスが得られますが、QueryImplementingThingsOptimized によってインデックシングクエリーを使用しない方が使用した場合よりもパフォーマンスが向上することがあります。1 つの既知の事例として、インデックスクエリーがモデル内の Thing の総数の 80 % 以上を返す場合が挙げられます。これらの場合、ThingWorx は QueryImplementingThingsOptimized がインデックスクエリーを使用しないでメモリ内キャッシュからのみクエリーを実行するようにするための "ヒント" をクエリーに含めます。詳細については、以下の「ヒント」「最良事例」のセクションを参照してください。
インデックシングは PostgreSQL、MS SQL、および Azure SQL データベースでサポートされています。H2 を使用している場合、H2 でアプリケーションをモデリングして作成できますが、プロパティはインデックシングされず、QueryImplementingThingsOptimized および QueryImplementingThingsOptimizedCount API ではパフォーマンス上の利点はありません。
インデックス付きプロパティを作成または更新すると、これらのプロパティがデータベースで永続になるまでに時間がかかります。プロパティの更新直後にインデックス付きプロパティに対して QueryImplementingThingsOptimizedWithTotalCount サービスを使用すると、不完全な結果または予期しない結果が返されます。2 秒後に QueryImplementingThingsOptimizedWithTotalCount サービスを再実行して正しい結果を取得します。
インデックシングの対象とするプロパティの決定
プロパティをインデックシングするかどうかを決定する際には、次の点に注意してください。
インデックシングは、プロパティのベースタイプ STRING、NUMBER、INTEGER、LONG、BOOLEAN、および文字列として保存されているベースタイプに制限されます。
* 
次のベースタイプは文字列として保存されます: DATETIME、THINGNAME、USERNAME、GROUPNAME、HYPERLINK、IMAGELINK、MASHUPNAME、MENUNAME、DASHBOARDNAME、TEXT、GUID、NOTIFICATIONCONTENTNAME、NOTIFICATIONDEFINITIONNAME、STYLETHEMENAME、および THINGGROUPNAME。
値が頻繁に変更されないかまったく変更されないプロパティのみをインデックシングの対象とする必要があります。頻繁に変更されるプロパティは対象としないでください。インデックシングするプロパティの例としては、モデル番号やシリアル番号などがあります。固定設備、都市、州、地域も対象にできます。
* 
テレメトリデータはインデックシングしないでください。
プロパティは QueryImplementingThingsOptimized を呼び出すときに使用される可能性があるでしょうか? すべてのインデックス付きプロパティは永続化も行われるので、プロパティをインデックシングすることで実用的な利点が得られるかどうかを考慮する必要があります。プロパティを永続化すると ThingWorx にオーバーヘッドが生じるので、QueryImplementingThingsOptimized で使用されないプロパティをインデックシングしてはなりません。
インデックス付きプロパティの設定
「インデックス」の設定は、エンティティのプロパティセクションにあります。詳細については、「Thing プロパティ」を参照してください。
インデックシングのバイト制限
インデックスのバイト長の制限により、文字列プロパティには次の制限があります。
永続化プロバイダとして MS SQL または Azure SQL を使用している場合、文字列は 1500 バイトに制限されます。文字列は MS SQL と Azure SQL では UTF-16 として保存されます。
永続化プロバイダとして PostgreSQL を使用している場合、文字列は 1000 バイトに制限されます。文字列は PostgreSQL では UTF-8 として保存されます。
最大バイト長を超える文字列値はインデックスに追加されず、インデックスクエリーには表示されません。この場合、値が大きすぎてインデックシングされなかったことを示すエラーがアプリケーションログに追加されます。文字列値はインデックシングされませんが、保存されて永続化されます。GetPropetyValues などの API は保存されている値をフェッチでき、再起動後に値を使用できます。文字列値が最大バイトの制限を超える可能性がある場合、データ変更イベントに対する通知を作成できます。
デフォルトプロパティのサポート
次の表に、すべての Thing に存在し、インデックスクエリーがサポートされているプロパティをリストします。
プロパティ名
プロパティタイプ
インデックスクエリーをサポートするか?
name
STRING
はい
description
STRING
はい
tags
TAGS
はい
isSystemObject
BOOLEAN
いいえ
homeMashup
STRING
いいえ
avatar
IMAGE
いいえ
projectName
STRING
いいえ
thingTemplate
STRING
はい
QueryImplementingThingsOptimized のユーザー入力パラメータ
QueryImplementingThingsOptimized の実行時に次の操作を実行できます。
操作名
注記
潜在的な最適化状態 (リクエスト時に指定され Null でない場合)
ResultDefinition
API 呼び出し時にパラメータ basicPropertyNames および propertyNames によって指定されます。
basicPropertyNames - 結果を返す基本プロパティのリスト。
propertyNames - 結果を返す組み込みプロパティと実装エンティティプロパティのリスト。
* 
リクエスト時に両方のパラメータが未定義または Null として指定されている場合、すべてのプロパティが結果に返されます。これには、すべての基本プロパティ、組み込みプロパティ、および実装エンティティに定義されているプロパティが含まれます。
リクエストされたすべてのプロパティ定義がインデックシングされている場合、QueryImplementingThingsOptimized はインデックスクエリーを実行して結果セットを生成します。
リクエストされたプロパティ定義の一部がインデックシングされ、その操作がサポートされている場合、QueryImplementingThingsOptimized はインデックス付きプロパティに対してインデックスクエリーを実行し、その結果セットを使用して、メモリ内キャッシュでインデックスなしプロパティをクエリーします。
リクエストされたプロパティ定義のいずれもインデックシングされていないか、パラメータが Null の場合、QueryImplementingThingsOptimized はメモリ内キャッシュをクエリーします。
NameMask
Thing 名を照合するマスク状のパターン。
NameMask は QueryImplementingThingsOptimized がインデックスクエリーを使用するかどうかについて影響しません。
NetworkName
所定の実装 Thing が属するネットワーク名。ヒントを指定できます。たとえば、ネットワークの最大深さと親ネットワーク名を指定することでサーチを絞り込むことができます。
QueryImplementingThingsOptimized はメモリ内キャッシュに対してクエリーを実行します。
Tags
結果に含めるエンティティに付いている必要があるタグのリスト。
QueryImplementingThingsOptimized はタグにインデックスクエリーを使用します。
Offset
ページ付けに使用される、クエリー開始のオフセット。たとえば、データベース内に 200 個の結果があり、オフセットが 5 に設定されている場合、5 から 200 までの結果 (合計 195) が返されます。
Offset は QueryImplementingThingsOptimized がインデックスクエリーを使用するかどうかについて影響しません。
Sort
最終結果に適用する並べ替え。
並べ替えで定義されているすべてのプロパティがインデックシングされている場合、QueryImplementingThingsOptimized はインデックスクエリーを実行して結果セットを生成します。
並べ替えの一部のプロパティがインデックシングされていない場合、QueryImplementingThingsOptimized はメモリ内キャッシュに対してクエリーを実行します。
Query
結果レコードに適用するフィルタ。
リクエストされたすべてのプロパティ定義がインデックシングされている場合、QueryImplementingThingsOptimized はインデックスクエリーを実行して結果セットを生成します。
リクエストされたプロパティ定義の一部がインデックシングされ、その操作がサポートされている場合、QueryImplementingThingsOptimized はインデックス付きプロパティに対してインデックスクエリーを実行し、その結果セットを使用して、メモリ内キャッシュでインデックスなしプロパティをクエリーします。
リクエストされたプロパティ定義のいずれもインデックシングされていない場合、QueryImplementingThingsOptimized はメモリ内キャッシュをクエリーします。
Limit
結果に含めるアイテムの最大数。
Limit は QueryImplementingThingsOptimized がインデックスクエリーを使用するかどうかについて影響を与えません。
ヒント
QueryImplementingThingsOptimized のクエリーパラメータにヒントを含めることで、データベースインデックスクエリーを無効にできます。
ヒント
必須
デフォルト
操作
optimizationDisabled
いいえ
含まれない
クエリーが指定されていないか、ヒントがクエリーに含まれていないか false の場合、QueryImplementingThingsOptimized は前述のようにクエリーを試みます。
インデックスクエリーを使用しないクエリーの例を次に示します。ここで、TT_1_Boolean1 はインデックス付きプロパティです。
query: {
"optimizationDisabled": true,
"sorts": [
{
"fieldName": "name"
}
],
"filters": {
"type": "EQ",
"fieldName": "TT_1_Boolean1",
"value": true
}
} /* QUERY */ ,
プロパティのベースタイプの移行
既存のプロパティのプロパティベースタイプを変更できます。インデックス付きプロパティをサポートするため、次のような移行シナリオが存在します。
プロパティに値が設定されている場合、ThingWorx はプロパティ値を新しいベースタイプに変換しようとします。たとえば、値が "String123" の文字列プロパティを整数に変換した場合、新しい整数値は 123 になります。逆に、123 の整数プロパティを文字列に変換すると、このプロパティは "123" になります。
プロパティ値が設定されておらず、新しいベースタイプにデフォルト値が定義されている場合、すべてのクエリーでその値が使用されます。
プロパティのデフォルト値が定義されていない場合、ThingWorx は新しいベースタイプのデフォルト値を使用します。たとえば、整数と数値はゼロ (0) に設定され、文字列は空の文字列 ("") に設定されます。
次の 2 つの表に、クエリーでインデックスクエリーが使用される場合の例を示します。モデルの例については 1 つ目の表で詳しく説明し、QueryImplementingThingsOptimized の動作の例については 2 つ目の表で詳しく説明しています。
モデル
次のモデルは、インデックス付きプロパティの使用方法を示しています。このモデルの例では、Thing Template とそのテンプレートに基づいた 2 つの Thing が使用されています。この継承は、Thing Template によって実装されている Thing Shape を使用して実現することもできます。
エンティティ名
エンティティタイプ
実装
プロパティ名
プロパティタイプ
インデックシング付きプロパティ?
TestThingTemplate1
Thing Template
GenericThing
p1
INTEGER
はい
p2
STRING
はい
p3
INTEGER
いいえ
p4
STRING
いいえ
TestThing1
Thing
TestThingTemplate1
継承
継承
継承
TestThing2
Thing
TestThingTemplate1
継承
継承
継承
QueryImplementingThingsOptimized の最適化事例
シナリオ
インデックスクエリーを使用?
コメント
すべての操作がサポートされ、フィルタが完全にサポートされている。
{"sorts":[{"fieldName":"p1"}],"filters":{"type":"And","filters":[{"type":"EQ","fieldName":"p2","value":"12"},
{"type":"EQ","fieldName":"p1","value":"13"}]}}
はい
インデックス付きプロパティのみがクエリーされるので、これはインデックスクエリーを使用します。
すべての操作がサポートされ、フィルタが部分的にサポートされている。
{"sorts":[{"fieldName":"p1"}],
"filters":{"type":"And","filters":[{"type":"EQ","fieldName":"p4","value":"12"},{"type":"EQ","fieldName":"p1","value":"13"}]}}
はい
ThingWorx は、プロパティ P1 のインデックスクエリーを実行してから、その結果セットに対して P4 のキャッシュクエリーを実行します。
すべての操作がサポートされ、フィルタがサポートされていない。
{"sorts":[{"fieldName":"p1"}],"filters":
{"type":"Or","filters":[{"type":"EQ","fieldName":"p4","value":"12"},{"type":"EQ","fieldName":"p1","value":"13"}]}}
いいえ
OR フィルタによりインデックスクエリーには利点がないので、ThingWorx は完全なキャッシュクエリーを実行します。
すべての操作がサポートされ、フィルタはない。
{"sorts":[{"fieldName":"p1"}]}
いいえ
フィルタするものがないので、クエリーは実行されません。
一部の操作がサポートされ、フィルタが完全にサポートされている。
{"sorts":[{"fieldName":"p4"}],"filters":{"type":"And","filters":
[{"type":"EQ","fieldName":"p2","value":"12"},{"type":"EQ","fieldName":"p1","value":"13"}]}}
はい
フィルタ対象のフィールドがすべてインデックシングされているので、このクエリーはインデックスクエリーを使用します。
一部の操作がサポートされ、フィルタが部分的にサポートされている。
{"sorts":[{"fieldName":"p4"}],"filters":{"type":"And","filters":
[{"type":"EQ","fieldName":"p4","value":"12"},{"type":"EQ","fieldName":"p1","value":"13"}]}}
はい
インデックスがないプロパティに対して SORT が実行されることを除けば、これは 2 行目の例と同じです。
一部の操作がサポートされ、フィルタがサポートされていない。
{"sorts":[{"fieldName":"p4"}],"filters":{"type":"Or","filters":[{"type":"EQ","fieldName":"p4","value":"12"},
{"type":"EQ","fieldName":"p1","value":"13"}]}}
いいえ
フィルタは 3 行目の例と同じなので、このクエリーはインデックスクエリーをサポートしません。
一部の操作がサポートされ、フィルタが指定されていない。
{"sorts":[{"fieldName":"p4"}]}
いいえ
フィルタするものがないので、これはサポートされません。
タグがクエリーされ、フィルタが指定されていない。
はい
インデックスクエリーでは、タグのクエリーがサポートされています。
最良事例
アプリケーションのパフォーマンスをテストして、特定のユースケースでクエリー最適化を無効にするかどうかを決定します。
インデックスクエリーは、モデルの小さいサブセットを返す場合に最もパフォーマンスが高くなります。パフォーマンスの向上は単一の Thing をサーチする場合が最大となります。たとえば、シリアル番号によって単一の Thing をクエリーする場合にパフォーマンスが最も向上します。
クエリーによってモデルの 80 % 以上が返される場合、ヒントを使用してインデックスクエリーを無効にします。
プロパティのベースタイプの変更は、Thing Template または Thing Shape レベルでの変更をすべての実装エンティティに適用する必要があるので、費用がかかる操作です。大規模なモデルの場合、これには膨大な時間とリソースを要することがあります。
システムが取り込みを実行している間は、プロパティのベースタイプを修正しないでください。
永続化プロバイダの最大キューサイズが、インデックス付きプロパティを追加する際またはインデックス付きプロパティのベースタイプを変更する際に発生する永続化プロパティの書き込み件数に対応できる十分な大きさであることを確認してください。最大キューサイズは、プロパティの書き込み件数より大きくなければなりません。書き込み件数は、修正されたプロパティの数と、そのプロパティを実装する Thing の数を掛け合わせた数になります。たとえば、10,000 個の Thing によって実装されている Thing Template がモデルに含まれているとします。そのテンプレート上の 2 つのプロパティのベースタイプを変更した場合、永続化プロパティ書き込みキューに 20,000 件の書き込み (2 プロパティ X 10,000 Thing) が発生します。最大キューサイズのデフォルトサイズは 100,000 書き込みなので、この例では操作に十分なリソースがあります。
これは役に立ちましたか?