Rechercher des objets métier et des nœuds
L’API RealityConnect propose deux routes de recherche à la portée différente : la recherche d’objets métier explore l’intérieur d’un twin pour les POI, zones, assets et leurs métadonnées, tandis que la recherche de nœuds explore la hiérarchie de nœuds de votre organisation (sites, dossiers, twins et fichiers). Les deux routes sont expérimentales et peuvent évoluer.
Points de terminaison
Section intitulée « Points de terminaison »| Méthode | Chemin | Scope | Objectif |
|---|---|---|---|
GET | /v1/twin/{contextId}/search | Basic | Rechercher des objets métier et des métadonnées dans un twin |
GET | /v1/nodes/search | ReadHierarchy | Rechercher dans la hiérarchie de nœuds de l’organisation |
Recherche d’objets métier
Section intitulée « Recherche d’objets métier »GET /v1/twin/{contextId}/search recherche les POI, zones, box assets, mesures et autres objets métier dans un twin donné (ou l’un de ses sites/brouillons, identifié par contextId), en comparant le nom, les champs réservés, les métadonnées d’asset et les propriétés spécifiques à l’objet.
Paramètres de requête
Section intitulée « Paramètres de requête »| Paramètre | Type | Remarques |
|---|---|---|
fieldFilters | tableau d’objets JSON | Filtres à clés réservées. Voir ci-dessous. |
metadataFilters | tableau d’objets JSON | Compare les propriétés de métadonnées d’asset du twin. Voir ci-dessous. |
additionalPropertyFilters | tableau d’objets JSON | Compare les propriétés spécifiques au type d’objet (p. ex. l’icon d’un POI). Voir ci-dessous. |
page | entier | Positif, valeur par défaut 1. |
limit | entier | 1–50, valeur par défaut 50. |
searchNameQuery | chaîne | Filtre de nom dédié, indépendant du nom dans fieldFilters. |
nameMatch | exact | contains | Mode de comparaison pour searchNameQuery. Par défaut contains. |
createdById | uuid | Filtre par créateur. |
createdBefore / createdAfter | horodatage | Strictement avant/après. Format YYYY-MM-DDTHH:mm:ss (sans décalage de fuseau horaire, sans millisecondes). |
updatedBefore / updatedAfter | horodatage | Même format. |
sortBy | name | createdAt | updatedAt | Champ de tri. |
sortDir | ASC | DESC | Sens du tri. |
fieldFilters, metadataFilters et additionalPropertyFilters sont chacun envoyés sous forme d’une chaîne d’objet JSON par filtre, le paramètre étant répété pour plusieurs filtres :
?fieldFilters={"key":"type","values":["poi"]}&fieldFilters={"key":"type","values":["zone"]}Chaque objet de filtre a la forme { "key": string, "values": string[] }. Plusieurs valeurs dans le tableau values d’un filtre sont combinées avec OR.
fieldFilters n’accepte que ces clés réservées — toute autre clé est silencieusement ignorée :
| Clé | Correspond à |
|---|---|
type | Type d’objet métier. Accepte soit la valeur d’énumération (Poi, Zone, BoxAsset, CubePrimitive, PlanePrimitive, DistanceMeasure, CoordinateMeasure, DiameterMeasure, SurfaceMeasure, OrthogonalMeasure, Cut, ModelAsset), soit son jeton kebab-case normalisé — une version en minuscules avec traits d’union du nom PascalCase, p. ex. BoxAsset → box-asset. |
asset-type | Le type d’asset de l’objet (correspond à assetTypeId). Correspondance exacte. |
name | Correspondance par préfixe sur le nom uniquement, sans tolérance aux fautes. |
id | Correspondance exacte de l’identifiant de l’objet. |
Les valeurs de fieldFilters sont toujours de simples chaînes ou jetons d’énumération — la syntaxe numérique/de plage ci-dessous ne s’y applique pas.
metadataFilters et additionalPropertyFilters ciblent par clé une propriété de métadonnées définie par le schéma (metadataFilters) ou une propriété spécifique au type d’objet qui ne fait pas partie des métadonnées communes (additionalPropertyFilters, p. ex. l’icon d’un POI). Chaque valeur de values prend en charge :
| Syntaxe de valeur | Signification |
|---|---|
| Chaîne simple | Correspondance exacte. Plusieurs chaînes simples dans values sont combinées avec OR. |
* ou chaîne vide | Ignorée — si c’est la seule valeur, le filtre ne teste que la présence de la clé. |
=123, !=123, >123, >=123, <123, <=123 | Comparaison numérique. Entiers, décimaux et notation scientifique (p. ex. 1.5e+35) pris en charge. |
range:[1..10] | Plage numérique inclusive. |
range:(1..10) | Plage numérique exclusive. |
range:[1..10) / range:(1..10] | Bornes mixtes inclusive/exclusive. |
true / false | additionalPropertyFilters uniquement — compare littéralement une propriété booléenne. |
Combinaison des filtres
Section intitulée « Combinaison des filtres »fieldFilters, metadataFilters et additionalPropertyFilters se combinent selon une logique ET : un résultat doit satisfaire chaque filtre. Au sein d’un même filtre, les valeurs de son tableau values sont combinées avec OU — ainsi, deux objets fieldFilters partageant la même key se comportent comme « l’une ou l’autre valeur correspond », tandis que les filtres sur des clés différentes (ou des tableaux de filtres différents) restreignent tous davantage l’ensemble de résultats.
Filtre de type combiné à une plage numérique de métadonnées (POI dont la pression d’inspection enregistrée est comprise entre 80 et 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}Type d’asset combiné à un filtre de nom, mises à jour les plus récentes en premier :
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}Cela signifie : les objets dont le type d’asset est pump et dont le nom commence par « vibration », triés par date de mise à jour la plus récente.
Deux fieldFilters sur la même clé (combinés avec OU) associés à un fieldFilters sur une clé différente (combiné avec ET) — POI ou zones, restreints au type d’asset 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}Un littéral booléen additionalPropertyFilters combiné à une correspondance de chaîne metadataFilters — POI actifs dont les métadonnées liées à l’icône enregistrent un statut « warning » :
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}Une requête complète combinant les trois entrées de filtrage, un filtre de nom dédié, une plage de dates, la pagination et le tri — illustrant la forme complète de la requête :
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 | Trie par |
|---|---|
name | Nom de l’objet |
createdAt | Horodatage de création |
updatedAt | Horodatage de dernière mise à jour |
Chaque valeur de sortBy se combine avec l’une ou l’autre valeur de 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 vaut ASC par défaut lorsqu’il est omis. sortBy n’a pas de champ par défaut documenté — si vous l’omettez, le tri se fait par score de pertinence interne (ordre décroissant), avec id (ordre croissant) comme critère de départage. Seul fieldFilters avec key: "name" influe sur ce score ; tout autre filtre est une correspondance binaire pure, sans effet sur le classement, donc en pratique, omettre sortBy sans filtre name renvoie les résultats triés par id. Il s’agit d’un détail d’implémentation, et non d’un contrat garanti — définissez sortBy explicitement chaque fois qu’un ordre de champ précis importe pour votre intégration.
Filtres numériques et de plage
Section intitulée « Filtres numériques et de plage »Dans les valeurs de metadataFilters et additionalPropertyFilters, une valeur peut porter un opérateur de comparaison ou une plage au lieu d’une correspondance littérale. Cette syntaxe ne s’applique pas à fieldFilters — ces derniers utilisent toujours une correspondance littérale/d’énumération (type, asset-type, name, id).
| Opérateur | Exemple | Signification |
|---|---|---|
= | =123 | Égal à |
!= | !=123 | Différent de |
> | >123 | Supérieur à |
>= | >=123 | Supérieur ou égal à |
< | <123 | Inférieur à |
<= | <=123 | Inférieur ou égal à |
range:[a..b] | range:[80..120] | Inclusif sur les deux bornes |
range:(a..b) | range:(80..120) | Exclusif sur les deux bornes |
range:[a..b) | range:[80..120) | Borne inférieure inclusive, borne supérieure exclusive |
range:(a..b] | range:(80..120] | Borne inférieure exclusive, borne supérieure inclusive |
Les entiers, les décimaux, les nombres négatifs et la notation scientifique sont tous pris en charge, p. ex. >=-40, =3.14, ou range:[1.5e+35..2.0e+35].
Filtre de nom vs. requête de nom
Section intitulée « Filtre de nom vs. requête de nom »Il existe deux façons de faire correspondre un nom, et elles se comportent différemment :
| Paramètre | Style de correspondance | Se combine avec d’autres filtres ? |
|---|---|---|
fieldFilters={"key":"name",...} | Correspondance par préfixe, sans tolérance aux fautes | Oui — toujours combiné avec ET |
searchNameQuery + nameMatch | contains (par défaut) ou exact, sans tolérance aux fautes | Oui — toujours combiné avec ET |
Utilisez fieldFilters avec key: "name" pour une correspondance par préfixe portant uniquement sur le nom, qui suit les mêmes règles ET/OU que type ou asset-type. Utilisez searchNameQuery avec nameMatch lorsque vous avez besoin d’une recherche précise par sous-chaîne ou par nom exact, sans aucune tolérance aux fautes — par exemple pour vérifier qu’un nom existe tel quel.
{ "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 indique quel champ ou quelle propriété de métadonnées a correspondu, le texte correspondant étant entouré de <em>. matchKey est soit un nom de champ racine (p. ex. name), soit @<metadata-path> pour une valeur imbriquée de métadonnées ou de propriété correspondante.
Détails du surlignage
Section intitulée « Détails du surlignage »Un même résultat peut porter plusieurs entrées matchedFields — une par champ ou propriété de métadonnées ayant correspondu. Par exemple, une requête combinant une correspondance de nom fieldFilters et un metadataFilters qui correspond à la fois au nom de l’objet et à une valeur de métadonnées d’inspection renvoie :
{ "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"}Les fragments surlignés sont échappés en HTML avant l’insertion des balises <em> : tout <, > ou & présent dans le texte correspondant arrive sous la forme <, > ou & plutôt que comme balisage brut — ce qui permet de les afficher directement en HTML sans second passage d’échappement, mais pensez à les décoder d’abord si vous avez besoin de la valeur en texte brut.
Cas particuliers
Section intitulée « Cas particuliers »| Situation | Comportement |
|---|---|
| Aucun filtre (ou tous vides) | Renvoie tous les objets métier du twin, jusqu’à limit, sans classement (match_all). |
Une clé fieldFilters non reconnue | Silencieusement ignorée — le filtre ne contribue en rien à la requête, il ne déclenche pas d’erreur 400. |
Une valeur metadataFilters/additionalPropertyFilters égale à * ou "" | Ignorée. Si toutes les valeurs du tableau values de ce filtre sont ainsi ignorées, le filtre exige tout de même que l’objet possède une propriété à cette clé — il devient une simple vérification de présence de clé, sans contrainte sur la valeur. |
Exemples
Section intitulée « Exemples »Recherche par préfixe de nom :
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}Recherche par sous-chaîne de nom, triée par nom :
GET {api_url}/v1/twin/{contextId}/search?searchNameQuery=Pump&nameMatch=contains&sortBy=name&sortDir=ASCAuthorization: Bearer {access_token}Cas d’erreur
Section intitulée « Cas d’erreur »| Statut | Cause |
|---|---|
400 Bad Request | Une valeur de fieldFilters, metadataFilters ou additionalPropertyFilters n’est pas un JSON valide, ou ne correspond pas à la forme { key, values }. |
Exemple complet
Section intitulée « Exemple complet »Les paramètres de filtre répétés (plusieurs fieldFilters, metadataFilters ou additionalPropertyFilters avec des valeurs JSON différentes) ne peuvent pas être construits avec les params basés sur un dict de requests — un dict ne peut contenir qu’une seule valeur par clé. Construisez plutôt vous-même la chaîne de requête avec urllib.parse.urlencode et une liste de tuples :
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"])Recherche de nœuds
Section intitulée « Recherche de nœuds »GET /v1/nodes/search recherche dans la hiérarchie de nœuds de votre organisation — divisions, sites, dossiers, twins, bibliothèques d’assets et fichiers de données — plutôt que dans les objets métier d’un twin. L’organisation est déterminée à partir du jeton d’accès, et non transmise en paramètre.
Paramètres de requête
Section intitulée « Paramètres de requête »| Paramètre | Type | Remarques |
|---|---|---|
nodeTypes | tableau de DataNodeType | Filtre sur un ou plusieurs types de nœuds. Répétez le paramètre, p. ex. ?nodeTypes=Site&nodeTypes=Folder. Valeurs : Organization, Site, Pointcloud, Mesh, SiteFile, Folder, Project, Division, Artifact, DataBundle, Twin, AssetLibrary. |
excludeNodeTypes | tableau de DataNodeType | Exclut un ou plusieurs types de nœuds. Même syntaxe de répétition. |
searchNameQuery | chaîne | Filtre par nom de nœud. |
nameMatch | exact | contains | Mode de comparaison pour searchNameQuery. Par défaut contains. |
parentId | uuid | Uniquement les enfants directs de ce nœud. |
ancestorId | uuid | Descendants à toute profondeur, à l’exclusion de l’ancêtre lui-même. À utiliser pour le contenu imbriqué sous un site ou un dossier ; utilisez parentId pour les enfants directs uniquement. |
createdById | uuid | Filtre par créateur. |
createdBefore / createdAfter | horodatage | Strictement avant/après. Format YYYY-MM-DDTHH:mm:ss. |
updatedBefore / updatedAfter | horodatage | Même format. |
bytesStored | entier | Correspondance exacte. |
minBytesStored / maxBytesStored | entier | Bornes inclusives. |
childrenCount | entier | Correspondance exacte. |
minChildrenCount / maxChildrenCount | entier | Bornes inclusives. |
includesThumbnail | 'true' | 'false' | Inclut les URL de miniature signées lorsqu’elles sont disponibles. Par défaut 'false'. |
page | entier | Par défaut 1. |
limit | entier | 1–50, valeur par défaut 20. |
sortBy | name | createdAt | updatedAt | bytesStored | childrenCount | Champ de tri. |
sortDir | ASC | DESC | Sens du tri. Par défaut 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}Exemples
Section intitulée « Exemples »Tous les sites sous un nœud ancêtre :
GET {api_url}/v1/nodes/search?nodeTypes=Site&ancestorId=d2a1c4b7-3e10-4f2c-9a6b-7c1d8e2f3a45Authorization: Bearer {access_token}Dossiers dont le nom commence par « Archive », triés par nom :
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"])Étape suivante
Section intitulée « Étape suivante »Pour créer des ressources sous un nœud renvoyé par la recherche de nœuds, consultez Créer un data bundle.