Business-Objekte und Knoten durchsuchen
Die RealityConnect API stellt zwei Such-Routen mit unterschiedlichem Umfang bereit: Die Business-Objekt-Suche durchsucht innerhalb eines Twins POIs, Zonen, Assets und deren Metadaten, während die Knotensuche die Knotenhierarchie Ihrer Organisation (Sites, Ordner, Twins und Dateien) durchsucht. Beide Routen sind experimentell und können sich ändern.
Endpunkte
Abschnitt betitelt „Endpunkte“| Methode | Pfad | Scope | Zweck |
|---|---|---|---|
GET | /v1/twin/{contextId}/search | Basic | Business-Objekte und Metadaten innerhalb eines Twins durchsuchen |
GET | /v1/nodes/search | ReadHierarchy | Die Knotenhierarchie der Organisation durchsuchen |
Business-Objekte durchsuchen
Abschnitt betitelt „Business-Objekte durchsuchen“GET /v1/twin/{contextId}/search durchsucht POIs, Zonen, Box-Assets, Messungen und andere Business-Objekte innerhalb eines einzelnen Twins (oder einer seiner Sites/Entwürfe, identifiziert durch contextId) und trifft dabei auf Name, reservierte Felder, Asset-Metadaten und objektspezifische Eigenschaften.
Abfrageparameter
Abschnitt betitelt „Abfrageparameter“| Parameter | Typ | Hinweise |
|---|---|---|
fieldFilters | Array von JSON-Objekten | Filter mit reservierten Schlüsseln. Siehe unten. |
metadataFilters | Array von JSON-Objekten | Gleicht Asset-Metadateneigenschaften des Twins ab. Siehe unten. |
additionalPropertyFilters | Array von JSON-Objekten | Gleicht objekttypspezifische Eigenschaften ab (z. B. das icon eines POI). Siehe unten. |
page | Ganzzahl | Positiv, Standard 1. |
limit | Ganzzahl | 1–50, Standard 50. |
searchNameQuery | String | Eigener Namensfilter, unabhängig vom name in fieldFilters. |
nameMatch | exact | contains | Abgleichsmodus für searchNameQuery. Standard contains. |
createdById | UUID | Filter nach Ersteller. |
createdBefore / createdAfter | Zeitstempel | Streng davor/danach. Format YYYY-MM-DDTHH:mm:ss (kein Zeitzonen-Offset, keine Millisekunden). |
updatedBefore / updatedAfter | Zeitstempel | Gleiches Format. |
sortBy | name | createdAt | updatedAt | Sortierfeld. |
sortDir | ASC | DESC | Sortierrichtung. |
fieldFilters, metadataFilters und additionalPropertyFilters werden jeweils als ein JSON-Objekt-String pro Filter gesendet, für mehrere Filter wird der Query-Parameter wiederholt:
?fieldFilters={"key":"type","values":["poi"]}&fieldFilters={"key":"type","values":["zone"]}Jedes Filterobjekt hat die Form { "key": string, "values": string[] }. Mehrere Werte im values-Array eines Filters werden mit ODER verknüpft.
fieldFilters akzeptiert nur diese reservierten Schlüssel — jeder andere Schlüssel wird stillschweigend ignoriert:
| Schlüssel | Trifft auf |
|---|---|
type | Business-Objekttyp. Akzeptiert entweder den Enum-Wert (Poi, Zone, BoxAsset, CubePrimitive, PlanePrimitive, DistanceMeasure, CoordinateMeasure, DiameterMeasure, SurfaceMeasure, OrthogonalMeasure, Cut, ModelAsset) oder dessen normalisiertes Kebab-Case-Token — eine mit Bindestrichen versehene, kleingeschriebene Version des PascalCase-Namens, z. B. BoxAsset → box-asset. |
asset-type | Der Asset-Typ des Objekts (wird auf assetTypeId abgebildet). Exakter Abgleich. |
name | Präfixabgleich nur auf den Namen, ohne Unschärfe. |
id | Exakter Abgleich der Objekt-ID. |
fieldFilters-Werte sind immer einfache Strings oder Enum-Tokens — die unten beschriebene Numerik-/Bereichs-Syntax gilt hier nicht.
metadataFilters und additionalPropertyFilters adressieren per Schlüssel eine schema-definierte Metadateneigenschaft (metadataFilters) oder eine objekttypspezifische Eigenschaft, die nicht Teil der gemeinsamen Metadaten ist (additionalPropertyFilters, z. B. das icon eines POI). Jeder Wert in values unterstützt:
| Wert-Syntax | Bedeutung |
|---|---|
| Einfacher String | Exakter Abgleich. Mehrere einfache Strings in values werden mit ODER verknüpft. |
* oder leerer String | Wird übersprungen — ist er der einzige Wert, trifft der Filter allein auf das Vorhandensein des Schlüssels. |
=123, !=123, >123, >=123, <123, <=123 | Numerischer Vergleich. Ganzzahlen, Dezimalzahlen und wissenschaftliche Notation (z. B. 1.5e+35) werden unterstützt. |
range:[1..10] | Inklusiver Zahlenbereich. |
range:(1..10) | Exklusiver Zahlenbereich. |
range:[1..10) / range:(1..10] | Gemischte inklusive/exklusive Grenzen. |
true / false | Nur additionalPropertyFilters — gleicht eine boolesche Eigenschaft direkt ab. |
Filter kombinieren
Abschnitt betitelt „Filter kombinieren“fieldFilters, metadataFilters und additionalPropertyFilters werden mit UND-Semantik kombiniert: Ein Ergebnis muss jeden einzelnen Filter erfüllen. Innerhalb eines einzelnen Filters werden die Werte im values-Array mit ODER verknüpft — zwei fieldFilters-Objekte mit demselben key verhalten sich also wie „einer der beiden Werte trifft zu”, während Filter auf unterschiedliche Schlüssel (oder unterschiedliche Filter-Arrays) die Ergebnismenge jeweils weiter einschränken.
Typfilter kombiniert mit einem numerischen Metadatenbereich (POIs mit einem erfassten Inspektionsdruck zwischen 80 und 120):
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}Asset-Typ kombiniert mit einem Namensfilter, neueste Aktualisierungen zuerst:
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}Das bedeutet: Objekte, deren Asset-Typ pump ist und deren Name mit „vibration” beginnt, sortiert nach der zuletzt aktualisierten Reihenfolge.
Zwei fieldFilters auf demselben Schlüssel (ODER-verknüpft) kombiniert mit einem fieldFilters auf einem anderen Schlüssel (UND-verknüpft) — POIs oder Zonen, eingeschränkt auf den Asset-Typ 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}Ein boolesches additionalPropertyFilters-Literal kombiniert mit einem String-Abgleich in metadataFilters — aktive POIs, deren icon-nahe Metadaten einen „warning”-Status verzeichnen:
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}Eine vollständig ausgereizte Anfrage, die alle drei Filtereingaben, einen eigenen Namensfilter, einen Datumsbereich, Paginierung und Sortierung kombiniert — sie zeigt die vollständige Form einer Anfrage:
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}Sortierung
Abschnitt betitelt „Sortierung“sortBy | Sortiert nach |
|---|---|
name | Objektname |
createdAt | Erstellungszeitstempel |
updatedAt | Zeitstempel der letzten Aktualisierung |
Jeder sortBy-Wert lässt sich mit jedem sortDir-Wert kombinieren:
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 ist standardmäßig ASC, wenn nicht angegeben. Für sortBy gibt es kein dokumentiertes Standardfeld — wird er weggelassen, wird nach einem internen Relevanz-Score (absteigend) sortiert, mit id (aufsteigend) als Tiebreaker. Nur fieldFilters mit key: "name" beeinflusst diesen Score; jeder andere Filter ist ein reiner Ja/Nein-Abgleich ohne Einfluss auf das Ranking — wird sortBy also ohne einen name-Filter weggelassen, werden die Ergebnisse in der Praxis in id-Reihenfolge zurückgegeben. Dies ist ein Implementierungsdetail und keine garantierte Vertragsbedingung — setzen Sie sortBy daher immer explizit, wenn eine bestimmte Feldreihenfolge für Ihre Integration wichtig ist.
Numerik- und Bereichsfilter
Abschnitt betitelt „Numerik- und Bereichsfilter“Innerhalb von metadataFilters- und additionalPropertyFilters-Werten kann ein Wert statt eines Literalabgleichs einen Vergleichsoperator oder einen Bereich tragen. Diese Syntax gilt nicht für fieldFilters — dort wird immer literal/als Enum abgeglichen (type, asset-type, name, id).
| Operator | Beispiel | Bedeutung |
|---|---|---|
= | =123 | Gleich |
!= | !=123 | Ungleich |
> | >123 | Größer als |
>= | >=123 | Größer oder gleich |
< | <123 | Kleiner als |
<= | <=123 | Kleiner oder gleich |
range:[a..b] | range:[80..120] | Beide Grenzen inklusive |
range:(a..b) | range:(80..120) | Beide Grenzen exklusive |
range:[a..b) | range:[80..120) | Untere Grenze inklusive, obere exklusive |
range:(a..b] | range:(80..120] | Untere Grenze exklusive, obere inklusive |
Ganzzahlen, Dezimalzahlen, negative Zahlen und wissenschaftliche Notation werden alle unterstützt, z. B. >=-40, =3.14 oder range:[1.5e+35..2.0e+35].
Namensfilter vs. Namensabfrage
Abschnitt betitelt „Namensfilter vs. Namensabfrage“Es gibt zwei Wege, um nach Namen abzugleichen, und sie verhalten sich unterschiedlich:
| Parameter | Abgleichsstil | Kombinierbar mit anderen Filtern? |
|---|---|---|
fieldFilters={"key":"name",...} | Präfixabgleich, ohne Unschärfe | Ja — immer mit UND verknüpft |
searchNameQuery + nameMatch | contains (Standard) oder exact, ohne Unschärfe | Ja — immer mit UND verknüpft |
Verwenden Sie fieldFilters mit key: "name" für einen reinen Namens-Präfixabgleich, der sich unter denselben UND/ODER-Regeln kombiniert wie type oder asset-type. Verwenden Sie searchNameQuery mit nameMatch, wenn Sie eine präzise Teilstring- oder Exakt-Namenssuche ohne Unschärfe-Toleranz benötigen — zum Beispiel, um zu prüfen, ob ein Name wortgetreu existiert.
Antwort
Abschnitt betitelt „Antwort“{ "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 zeigt, welches Feld oder welche Metadateneigenschaft getroffen wurde, wobei der getroffene Text in <em> eingeschlossen ist. matchKey ist entweder ein Feldname der obersten Ebene (z. B. name) oder @<metadata-path> für einen getroffenen verschachtelten Metadaten- oder Eigenschaftswert.
Details zur Hervorhebung
Abschnitt betitelt „Details zur Hervorhebung“Ein einzelnes Ergebnis kann mehrere matchedFields-Einträge enthalten — einen pro Feld oder Metadateneigenschaft, die getroffen wurde. Zum Beispiel liefert eine kombinierte Anfrage aus einem fieldFilters-Namensabgleich und einer metadataFilters-Anfrage, die sowohl auf den Namen des Objekts als auch auf einen Inspektions-Metadatenwert trifft, Folgendes zurück:
{ "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"}Hervorhebungs-Fragmente werden HTML-escaped, bevor die <em>-Marker eingefügt werden — jedes <, > oder & im getroffenen Text kommt also als <, > oder & an statt als rohes Markup. Das ist sicher, um es direkt in HTML zu rendern, ohne einen zweiten Escaping-Durchlauf — dekodieren Sie es aber zuerst, wenn Sie den reinen Textwert benötigen.
Randfälle
Abschnitt betitelt „Randfälle“| Situation | Verhalten |
|---|---|
| Keine Filter (oder alle leer) | Gibt jedes Business-Objekt im Twin zurück, bis zu limit, ohne Ranking (match_all). |
Ein nicht erkannter fieldFilters-Schlüssel | Wird stillschweigend ignoriert — der Filter trägt nichts zur Abfrage bei, löst keinen 400 aus. |
Ein metadataFilters-/additionalPropertyFilters-Wert von * oder "" | Wird übersprungen. Werden alle Werte im values-Array eines Filters auf diese Weise übersprungen, verlangt der Filter weiterhin, dass das Objekt eine Eigenschaft mit diesem Schlüssel besitzt — er wird zu einer reinen Prüfung auf das Vorhandensein des Schlüssels, ohne Wertebeschränkung. |
Beispiele
Abschnitt betitelt „Beispiele“Namenspräfix-Suche:
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}Namenssuche (enthält), sortiert nach Name:
GET {api_url}/v1/twin/{contextId}/search?searchNameQuery=Pump&nameMatch=contains&sortBy=name&sortDir=ASCAuthorization: Bearer {access_token}Fehlerfälle
Abschnitt betitelt „Fehlerfälle“| Status | Ursache |
|---|---|
400 Bad Request | Ein Wert von fieldFilters, metadataFilters oder additionalPropertyFilters ist kein gültiges JSON oder entspricht nicht der Form { key, values }. |
Vollständiges Beispiel
Abschnitt betitelt „Vollständiges Beispiel“Wiederholte Filterparameter (mehrere fieldFilters, metadataFilters oder additionalPropertyFilters mit unterschiedlichen JSON-Werten) lassen sich nicht mit den dict-basierten params von requests abbilden — ein Dict kann pro Schlüssel nur einen Wert halten. Erstellen Sie den Query-String stattdessen selbst mit urllib.parse.urlencode und einer Liste von Tupeln:
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"])Knoten durchsuchen
Abschnitt betitelt „Knoten durchsuchen“GET /v1/nodes/search durchsucht die Knotenhierarchie Ihrer Organisation — Divisions, Sites, Ordner, Twins, Asset-Bibliotheken und Dateien — statt der Business-Objekte innerhalb eines Twins. Die Organisation wird aus dem Access Token ermittelt und nicht als Parameter übergeben.
Abfrageparameter
Abschnitt betitelt „Abfrageparameter“| Parameter | Typ | Hinweise |
|---|---|---|
nodeTypes | Array von DataNodeType | Filtert auf einen oder mehrere Knotentypen. Parameter wiederholen, z. B. ?nodeTypes=Site&nodeTypes=Folder. Werte: Organization, Site, Pointcloud, Mesh, SiteFile, Folder, Project, Division, Artifact, DataBundle, Twin, AssetLibrary. |
excludeNodeTypes | Array von DataNodeType | Schließt einen oder mehrere Knotentypen aus. Gleiche Wiederholungssyntax. |
searchNameQuery | String | Filter nach Knotenname. |
nameMatch | exact | contains | Abgleichsmodus für searchNameQuery. Standard contains. |
parentId | UUID | Nur direkte Kinder dieses Knotens. |
ancestorId | UUID | Nachfahren auf jeder Ebene, ohne den Vorfahren selbst. Für verschachtelte Inhalte unter einer Site oder einem Ordner; für direkte Kinder parentId verwenden. |
createdById | UUID | Filter nach Ersteller. |
createdBefore / createdAfter | Zeitstempel | Streng davor/danach. Format YYYY-MM-DDTHH:mm:ss. |
updatedBefore / updatedAfter | Zeitstempel | Gleiches Format. |
bytesStored | Ganzzahl | Exakter Abgleich. |
minBytesStored / maxBytesStored | Ganzzahl | Inklusive Grenzen. |
childrenCount | Ganzzahl | Exakter Abgleich. |
minChildrenCount / maxChildrenCount | Ganzzahl | Inklusive Grenzen. |
includesThumbnail | 'true' | 'false' | Signierte Thumbnail-URLs einschließen, sofern verfügbar. Standard 'false'. |
page | Ganzzahl | Standard 1. |
limit | Ganzzahl | 1–50, Standard 20. |
sortBy | name | createdAt | updatedAt | bytesStored | childrenCount | Sortierfeld. |
sortDir | ASC | DESC | Sortierrichtung. Standard ASC. |
Antwort
Abschnitt betitelt „Antwort“{ "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}Beispiele
Abschnitt betitelt „Beispiele“Alle Sites unter einem Vorfahrenknoten:
GET {api_url}/v1/nodes/search?nodeTypes=Site&ancestorId=d2a1c4b7-3e10-4f2c-9a6b-7c1d8e2f3a45Authorization: Bearer {access_token}Ordner, deren Name mit “Archive” beginnt, sortiert nach Name:
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"])Nächster Schritt
Abschnitt betitelt „Nächster Schritt“Um Ressourcen unter einem von der Knotensuche zurückgegebenen Knoten zu erstellen, siehe Einen Data Bundle erstellen.