ビジネスオブジェクトとノードの検索
RealityConnect APIには、対象範囲の異なる2つの検索ルートがあります。ビジネスオブジェクト検索はtwin内のPOI、ゾーン、アセット、およびそのメタデータを対象とし、ノード検索は組織のノード階層(サイト、フォルダ、twin、ファイル)を対象とします。どちらのルートも実験的なもので、変更される可能性があります。
エンドポイント
Section titled “エンドポイント”| メソッド | パス | スコープ | 目的 |
|---|---|---|---|
GET | /v1/twin/{contextId}/search | Basic | twin内のビジネスオブジェクトとメタデータを検索 |
GET | /v1/nodes/search | ReadHierarchy | 組織のノード階層を検索 |
ビジネスオブジェクトの検索
Section titled “ビジネスオブジェクトの検索”GET /v1/twin/{contextId}/search は、単一のtwin(またはcontextIdで指定されたそのサイト/ドラフトの1つ)内のPOI、ゾーン、box asset、計測、その他のビジネスオブジェクトを対象に、名前・予約フィールド・アセットメタデータ・オブジェクト固有プロパティに一致するものを検索します。
クエリパラメータ
Section titled “クエリパラメータ”| パラメータ | 型 | 備考 |
|---|---|---|
fieldFilters | JSONオブジェクトの配列 | 予約キーによるフィルタ。以下を参照。 |
metadataFilters | JSONオブジェクトの配列 | twinのアセットメタデータプロパティに一致。以下を参照。 |
additionalPropertyFilters | JSONオブジェクトの配列 | オブジェクトタイプ固有のプロパティ(例:POIのicon)に一致。以下を参照。 |
page | 整数 | 正の値、デフォルト1。 |
limit | 整数 | 1〜50、デフォルト50。 |
searchNameQuery | 文字列 | fieldFiltersの名前とは独立した専用の名前フィルタ。 |
nameMatch | exact | contains | searchNameQueryの一致モード。デフォルトcontains。 |
createdById | uuid | 作成者でフィルタ。 |
createdBefore / createdAfter | タイムスタンプ | 厳密にその前/後。形式はYYYY-MM-DDTHH:mm:ss(タイムゾーンオフセットなし、ミリ秒なし)。 |
updatedBefore / updatedAfter | タイムスタンプ | 同じ形式。 |
sortBy | name | createdAt | updatedAt | ソートフィールド。 |
sortDir | ASC | DESC | ソート方向。 |
fieldFilters、metadataFilters、additionalPropertyFiltersは、それぞれ1フィルタにつき1つのJSONオブジェクト文字列として送信され、複数のフィルタの場合はクエリパラメータを繰り返します。
?fieldFilters={"key":"type","values":["poi"]}&fieldFilters={"key":"type","values":["zone"]}各フィルタオブジェクトは{ "key": string, "values": string[] }の形をしています。1つのフィルタのvalues配列内の複数の値はOR結合されます。
**fieldFilters**は次の予約キーのみを受け付けます。それ以外のキーは黙って無視されます。
| キー | 一致対象 |
|---|---|
type | ビジネスオブジェクトタイプ。列挙値(Poi、Zone、BoxAsset、CubePrimitive、PlanePrimitive、DistanceMeasure、CoordinateMeasure、DiameterMeasure、SurfaceMeasure、OrthogonalMeasure、Cut、ModelAsset)、またはその正規化されたkebab-caseトークン(PascalCase名をハイフン区切り・小文字化したもの、例:BoxAsset → box-asset)のいずれかを受け付けます。 |
asset-type | オブジェクトのアセットタイプ(assetTypeIdにマッピング)。完全一致。 |
name | 名前のみの前方一致、あいまい性なし。 |
id | オブジェクトIDの完全一致。 |
fieldFiltersの値は常に単純な文字列または列挙トークンです。以下の数値/範囲構文はここには適用されません。
**metadataFiltersとadditionalPropertyFilters**は、キーによってスキーマ定義のメタデータプロパティ(metadataFilters)、または共通メタデータに含まれないオブジェクトタイプ固有のプロパティ(additionalPropertyFilters、例:POIのicon)を対象にします。values内の各値は次をサポートします。
| 値の構文 | 意味 |
|---|---|
| 単純な文字列 | 完全一致。values内の複数の単純な文字列はOR結合されます。 |
*または空文字列 | スキップされます — それが唯一の値である場合、フィルタはキーの存在のみに一致します。 |
=123、!=123、>123、>=123、<123、<=123 | 数値比較。整数、小数、指数表記(例:1.5e+35)に対応。 |
range:[1..10] | 数値の閉区間(境界含む)。 |
range:(1..10) | 数値の開区間(境界含まない)。 |
range:[1..10) / range:(1..10] | 境界の含む/含まないが混在する範囲。 |
true / false | additionalPropertyFiltersのみ — ブール値プロパティにそのまま一致します。 |
フィルタの組み合わせ
Section titled “フィルタの組み合わせ”fieldFilters、metadataFilters、additionalPropertyFiltersはANDセマンティクスで組み合わされます。つまり、結果はすべてのフィルタを満たす必要があります。単一のフィルタ内では、values配列内の値はOR結合されます — そのため、同じkeyを共有する2つのfieldFiltersオブジェクトは「どちらかの値が一致する」ように振る舞う一方、異なるキー(または異なるフィルタ配列)に対するフィルタは、それぞれが結果セットをさらに絞り込みます。
タイプフィルタと数値メタデータ範囲の組み合わせ(検査圧力が80〜120の範囲に記録されているPOI):
GET {api_url}/v1/twin/{contextId}/search?fieldFilters=%7B%22key%22%3A%22type%22%2C%22values%22%3A%5B%22poi%22%5D%7D&metadataFilters=%7B%22key%22%3A%22inspection.pressure%22%2C%22values%22%3A%5B%22range%3A%5B80..120%5D%22%5D%7DAuthorization: Bearer {access_token}アセットタイプと名前フィルタの組み合わせ、最新の更新順:
GET {api_url}/v1/twin/{contextId}/search?fieldFilters=%7B%22key%22%3A%22asset-type%22%2C%22values%22%3A%5B%22pump%22%5D%7D&fieldFilters=%7B%22key%22%3A%22name%22%2C%22values%22%3A%5B%22vibration%22%5D%7D&sortBy=updatedAt&sortDir=DESCAuthorization: Bearer {access_token}これは次のことを意味します。アセットタイプがpumpでかつ名前が「vibration」で始まるオブジェクトを、最終更新日時が新しい順にソートします。
同じキーに対する2つのfieldFilters(OR結合)と、異なるキーに対するfieldFilters(AND結合)の組み合わせ — POIまたはゾーンを、pumpアセットタイプに限定:
GET {api_url}/v1/twin/{contextId}/search?fieldFilters=%7B%22key%22%3A%22type%22%2C%22values%22%3A%5B%22poi%22%2C%22zone%22%5D%7D&fieldFilters=%7B%22key%22%3A%22asset-type%22%2C%22values%22%3A%5B%22pump%22%5D%7DAuthorization: Bearer {access_token}ブール値のadditionalPropertyFiltersリテラルと文字列のmetadataFilters一致の組み合わせ — アイコン周辺のメタデータが「warning」ステータスを記録しているアクティブなPOI:
GET {api_url}/v1/twin/{contextId}/search?fieldFilters=%7B%22key%22%3A%22type%22%2C%22values%22%3A%5B%22poi%22%5D%7D&additionalPropertyFilters=%7B%22key%22%3A%22isActive%22%2C%22values%22%3A%5B%22true%22%5D%7D&metadataFilters=%7B%22key%22%3A%22inspection.status%22%2C%22values%22%3A%5B%22warning%22%5D%7DAuthorization: Bearer {access_token}3つのフィルタ入力すべて、専用の名前フィルタ、日付範囲、ページネーション、ソートを組み合わせたフル装備のリクエスト — リクエスト全体の形を示します:
GET {api_url}/v1/twin/{contextId}/search?fieldFilters=%7B%22key%22%3A%22type%22%2C%22values%22%3A%5B%22poi%22%2C%22zone%22%5D%7D&metadataFilters=%7B%22key%22%3A%22inspection.pressure%22%2C%22values%22%3A%5B%22range%3A%5B80..120%5D%22%5D%7D&additionalPropertyFilters=%7B%22key%22%3A%22isActive%22%2C%22values%22%3A%5B%22true%22%5D%7D&searchNameQuery=Pump&nameMatch=contains&updatedAfter=2026-01-01T00%3A00%3A00&updatedBefore=2026-12-31T23%3A59%3A59&page=1&limit=25&sortBy=updatedAt&sortDir=DESCAuthorization: Bearer {access_token}sortBy | ソート対象 |
|---|---|
name | オブジェクト名 |
createdAt | 作成タイムスタンプ |
updatedAt | 最終更新タイムスタンプ |
各sortByの値は、どちらのsortDirの値とも組み合わせられます:
GET {api_url}/v1/twin/{contextId}/search?fieldFilters=%7B%22key%22%3A%22type%22%2C%22values%22%3A%5B%22poi%22%5D%7D&sortBy=name&sortDir=ASCAuthorization: Bearer {access_token}GET {api_url}/v1/twin/{contextId}/search?fieldFilters=%7B%22key%22%3A%22type%22%2C%22values%22%3A%5B%22poi%22%5D%7D&sortBy=createdAt&sortDir=DESCAuthorization: Bearer {access_token}GET {api_url}/v1/twin/{contextId}/search?fieldFilters=%7B%22key%22%3A%22type%22%2C%22values%22%3A%5B%22poi%22%5D%7D&sortBy=updatedAt&sortDir=DESCAuthorization: Bearer {access_token}sortDirは省略時ASCがデフォルトです。sortByにはドキュメント化されたデフォルトフィールドがありません — 省略した場合、内部的な関連度スコア(降順)でソートされ、id(昇順)がタイブレーカーとして使用されます。そのスコアに影響するのはkey: "name"を指定したfieldFiltersのみで、それ以外のフィルタはすべて単純な一致/不一致の判定であり、ランキングには影響しません。そのため実際には、nameフィルタなしでsortByを省略すると、結果はid順で返されます。これは実装の詳細であり、保証された仕様ではありません — 統合において特定のフィールド順序が重要な場合は、必ずsortByを明示的に設定してください。
数値・範囲フィルタ
Section titled “数値・範囲フィルタ”metadataFiltersとadditionalPropertyFiltersの値の内部では、値がリテラル一致の代わりに比較演算子や範囲を持つことができます。この構文はfieldFiltersには適用されません — fieldFilters(type、asset-type、name、id)は常にリテラル/列挙一致です。
| 演算子 | 例 | 意味 |
|---|---|---|
= | =123 | 等しい |
!= | !=123 | 等しくない |
> | >123 | より大きい |
>= | >=123 | 以上 |
< | <123 | より小さい |
<= | <=123 | 以下 |
range:[a..b] | range:[80..120] | 両端を含む区間 |
range:(a..b) | range:(80..120) | 両端を含まない区間 |
range:[a..b) | range:[80..120) | 下端を含み上端を含まない |
range:(a..b] | range:(80..120] | 下端を含まず上端を含む |
整数、小数、負の数、指数表記はすべてサポートされています。例:>=-40、=3.14、range:[1.5e+35..2.0e+35]。
名前フィルタ vs. 名前クエリ
Section titled “名前フィルタ vs. 名前クエリ”名前を一致させる方法は2種類あり、それぞれ動作が異なります。
| パラメータ | 一致スタイル | 他のフィルタとの組み合わせ |
|---|---|---|
fieldFilters={"key":"name",...} | 前方一致、あいまい性なし | はい — 常にANDされます |
searchNameQuery + nameMatch | contains(デフォルト)またはexact、あいまい性なし | はい — 常にANDされます |
typeやasset-typeと同じAND/ORルールで組み合わせられる、名前のみの前方一致には、key: "name"を指定したfieldFiltersを使用してください。あいまい性のない正確な部分一致または完全一致の名前検索が必要な場合(例えば、名前が完全一致で存在することを検証する場合)は、searchNameQueryとnameMatchを使用してください。
{ "results": [ { "id": "5e1c0b3a-2d9a-4b7d-8f0b-9a2c8f1b7a10", "name": "Fire extinguisher 12", "type": "Poi", "matchedFields": [ { "matchKey": "name", "highlight": "Fire <em>extinguisher</em> 12" } ], "createdAt": "2026-06-01T10:00:00.000Z", "updatedAt": "2026-06-01T10:00:00.000Z", "createdById": "8f0b9a2c-8f1b-4a10-9e1c-0b3a2d9a4b7d" } ], "count": 1}matchedFieldsは、どのフィールドまたはメタデータプロパティが一致したかを示し、一致したテキストは<em>で囲まれます。matchKeyは、ルートフィールド名(例:name)、または一致したネストされたメタデータ/プロパティ値を示す@<metadata-path>のいずれかです。
ハイライトの詳細
Section titled “ハイライトの詳細”1つの結果は、一致したフィールドまたはメタデータプロパティごとに1つずつ、複数のmatchedFieldsエントリを持つことができます。例えば、fieldFiltersの名前一致と、検査メタデータ値にも一致するmetadataFiltersを組み合わせたリクエストは、次のように返します。
{ "id": "5e1c0b3a-2d9a-4b7d-8f0b-9a2c8f1b7a10", "name": "Pressure gauge 04", "type": "Poi", "matchedFields": [ { "matchKey": "name", "highlight": "<em>Pressure</em> gauge 04" }, { "matchKey": "@inspection.status", "highlight": "<em>Warning</em>: recalibration due" } ], "createdAt": "2026-06-01T10:00:00.000Z", "updatedAt": "2026-06-01T10:00:00.000Z", "createdById": "8f0b9a2c-8f1b-4a10-9e1c-0b3a2d9a4b7d"}ハイライトフラグメントは、<em>マーカーが挿入される前にHTMLエスケープされます。そのため、一致したテキスト内の<、>、&は生のマークアップとしてではなく、それぞれ<、>、&として渡されます — 2回目のエスケープなしでHTMLに直接レンダリングしても安全ですが、プレーンテキストの値が必要な場合はまずデコードしてください。
エッジケース
Section titled “エッジケース”| 状況 | 動作 |
|---|---|
| フィルタが一切指定されていない(またはすべて空) | ランキングなし(match_all)で、twin内のすべてのビジネスオブジェクトをlimitまで返します。 |
認識されないfieldFiltersキー | 黙って無視されます — そのフィルタはクエリに何も寄与せず、400を発生させません。 |
metadataFilters/additionalPropertyFiltersの値が*または"" | スキップされます。そのフィルタのvalues配列内のすべての値がこのようにスキップされた場合でも、フィルタはそのキーにプロパティが存在することをオブジェクトに要求し続けます — 値の制約のないキー存在チェックになります。 |
名前の前方一致検索:
GET {api_url}/v1/twin/{contextId}/search?fieldFilters=%7B%22key%22%3A%22name%22%2C%22values%22%3A%5B%22extinguisher%22%5D%7DAuthorization: Bearer {access_token}名前の部分一致検索を名前でソート:
GET {api_url}/v1/twin/{contextId}/search?searchNameQuery=Pump&nameMatch=contains&sortBy=name&sortDir=ASCAuthorization: Bearer {access_token}エラーケース
Section titled “エラーケース”| ステータス | 原因 |
|---|---|
400 Bad Request | fieldFilters、metadataFilters、additionalPropertyFiltersのいずれかの値が有効なJSONでない、または{ key, values }の形に一致しない。 |
繰り返しのフィルタパラメータ(異なるJSON値を持つ複数のfieldFilters、metadataFilters、additionalPropertyFilters)は、requestsのdictベースのparamsでは構築できません — dictはキーごとに1つの値しか保持できないためです。代わりにurllib.parse.urlencodeとタプルのリストを使って自分でクエリ文字列を組み立ててください。
import jsonimport requestsfrom urllib.parse import urlencode
API_URL = "https://<your-regional-api-url>"TOKEN = "<access_token>"CONTEXT_ID = "<twin-id>"
headers = {"Authorization": f"Bearer {TOKEN}"}
params = [ ("fieldFilters", json.dumps({"key": "type", "values": ["poi"]})), ("metadataFilters", json.dumps({"key": "inspection.pressure", "values": ["range:[80..120]"]})), ("sortBy", "name"), ("sortDir", "ASC"),]
response = requests.get( f"{API_URL}/v1/twin/{CONTEXT_ID}/search?{urlencode(params)}", headers=headers,).json()
for result in response["results"]: print(result["type"], result["name"], result["id"])ノードの検索
Section titled “ノードの検索”GET /v1/nodes/search は、twin内のビジネスオブジェクトではなく、組織のノード階層 — division、サイト、フォルダ、twin、アセットライブラリ、データファイル — を検索します。組織はアクセストークンから解決され、パラメータとして渡すものではありません。
クエリパラメータ
Section titled “クエリパラメータ”| パラメータ | 型 | 備考 |
|---|---|---|
nodeTypes | DataNodeTypeの配列 | 1つ以上のノードタイプでフィルタします。パラメータを繰り返します(例:?nodeTypes=Site&nodeTypes=Folder)。値:Organization、Site、Pointcloud、Mesh、SiteFile、Folder、Project、Division、Artifact、DataBundle、Twin、AssetLibrary。 |
excludeNodeTypes | DataNodeTypeの配列 | 1つ以上のノードタイプを除外します。繰り返し構文は同じです。 |
searchNameQuery | 文字列 | ノード名でフィルタ。 |
nameMatch | exact | contains | searchNameQueryの一致モード。デフォルトcontains。 |
parentId | uuid | このノードの直接の子のみ。 |
ancestorId | uuid | 祖先自身を除く、任意の深さの子孫。サイトやフォルダ配下のネストされたコンテンツにはこちらを使用し、直接の子のみが必要な場合はparentIdを使用します。 |
createdById | uuid | 作成者でフィルタ。 |
createdBefore / createdAfter | タイムスタンプ | 厳密にその前/後。形式はYYYY-MM-DDTHH:mm:ss。 |
updatedBefore / updatedAfter | タイムスタンプ | 同じ形式。 |
bytesStored | 整数 | 完全一致。 |
minBytesStored / maxBytesStored | 整数 | 境界を含む範囲。 |
childrenCount | 整数 | 完全一致。 |
minChildrenCount / maxChildrenCount | 整数 | 境界を含む範囲。 |
includesThumbnail | 'true' | 'false' | 利用可能な場合、署名付きサムネイルURLを含めます。デフォルト'false'。 |
page | 整数 | デフォルト1。 |
limit | 整数 | 1〜50、デフォルト20。 |
sortBy | name | createdAt | updatedAt | bytesStored | childrenCount | ソートフィールド。 |
sortDir | ASC | DESC | ソート方向。デフォルトASC。 |
{ "items": [ { "id": "a6f75b3c-f261-4b27-9a2a-9a6cc1234c53", "createdAt": "2026-06-01T10:00:00.000Z", "updatedAt": "2026-06-01T10:00:00.000Z", "name": "Building A", "type": "Site", "createdById": "8f0b9a2c-8f1b-4a10-9e1c-0b3a2d9a4b7d", "parentId": "d2a1c4b7-3e10-4f2c-9a6b-7c1d8e2f3a45", "childrenCount": 4, "bytesStored": 15728640, "thumbnailSignedUrl": null } ], "total": 1}祖先ノード配下のすべてのサイト:
GET {api_url}/v1/nodes/search?nodeTypes=Site&ancestorId=d2a1c4b7-3e10-4f2c-9a6b-7c1d8e2f3a45Authorization: Bearer {access_token}名前が「Archive」で始まるフォルダを名前でソート:
GET {api_url}/v1/nodes/search?nodeTypes=Folder&searchNameQuery=Archive&nameMatch=contains&sortBy=name&sortDir=ASCAuthorization: Bearer {access_token}import requestsfrom urllib.parse import urlencode
API_URL = "https://<your-regional-api-url>"TOKEN = "<access_token>"ANCESTOR_ID = "<division-or-site-id>"
headers = {"Authorization": f"Bearer {TOKEN}"}
params = [ ("nodeTypes", "Site"), ("ancestorId", ANCESTOR_ID), ("sortBy", "name"), ("sortDir", "ASC"),]
response = requests.get( f"{API_URL}/v1/nodes/search?{urlencode(params)}", headers=headers,).json()
for node in response["items"]: print(node["type"], node["name"], node["id"])次のステップ
Section titled “次のステップ”ノード検索で返されたノード配下にリソースを作成するには、データバンドルの作成を参照してください。