industrial-model 0.5.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +723 -545
- package/dist/cognite-core/index.cjs +1882 -0
- package/dist/cognite-core/index.cjs.map +1 -0
- package/dist/cognite-core/index.d.cts +535 -0
- package/dist/cognite-core/index.d.ts +535 -0
- package/dist/cognite-core/index.js +1879 -0
- package/dist/cognite-core/index.js.map +1 -0
- package/dist/index.cjs +544 -193
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -263
- package/dist/index.d.ts +8 -263
- package/dist/index.js +545 -192
- package/dist/index.js.map +1 -1
- package/dist/types-2jjbs2i7.d.cts +267 -0
- package/dist/types-2jjbs2i7.d.ts +267 -0
- package/package.json +11 -1
package/README.md
CHANGED
|
@@ -2,32 +2,37 @@
|
|
|
2
2
|
|
|
3
3
|
TypeScript SDK for querying [Cognite Flexible Data Models (FDM)](https://docs.cognite.com/cdf/data_modeling/) with a type-safe, graph-aware API.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
`industrial-model` is designed for application code that needs to move through industrial data as a model, not as loosely typed query payloads. Start with a Cognite data model, describe the view shape in TypeScript, and query nodes, relations, filters, sorting, pagination, and aggregations with compiler support.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
- **
|
|
10
|
-
- **
|
|
11
|
-
- **
|
|
7
|
+
## What You Get
|
|
8
|
+
|
|
9
|
+
- **Typed model queries** - validate selected fields, filters, and sort keys at compile time.
|
|
10
|
+
- **Precise result types** - returned items follow the `select` tree, including nested relation selections.
|
|
11
|
+
- **Graph traversal** - expand direct, reverse, and edge relations up to 3 levels deep.
|
|
12
|
+
- **Industrial filters** - combine scalar filters, list filters, full-text search, and nested relation filters.
|
|
13
|
+
- **Pagination support** - use cursors manually or fetch all root pages with `limit: -1`.
|
|
14
|
+
- **Aggregation support** - count, group, list distinct values, and aggregate numeric properties.
|
|
15
|
+
- **Mutation support** - upsert model-shaped node patches and delete nodes by identity.
|
|
16
|
+
- **Runtime validation option** - parse query results with Zod schemas derived from Cognite view metadata.
|
|
17
|
+
- **CJS and ESM builds** - works in Node.js and common bundler setups.
|
|
12
18
|
|
|
13
19
|
## Installation
|
|
14
20
|
|
|
15
21
|
```bash
|
|
16
22
|
npm install industrial-model
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
`@cognite/sdk` is a peer dependency and must be installed separately:
|
|
20
|
-
|
|
21
|
-
```bash
|
|
22
23
|
npm install @cognite/sdk
|
|
23
24
|
```
|
|
24
25
|
|
|
26
|
+
`@cognite/sdk` is a peer dependency and must be installed by your application.
|
|
27
|
+
|
|
25
28
|
## Requirements
|
|
26
29
|
|
|
27
30
|
- Node.js `>=20`
|
|
28
|
-
- `@cognite/sdk` `^10.10.0`
|
|
31
|
+
- `@cognite/sdk` `^10.10.0`
|
|
29
32
|
|
|
30
|
-
##
|
|
33
|
+
## First Query
|
|
34
|
+
|
|
35
|
+
Create a Cognite SDK client, point `IndustrialModelClient` at a data model, and query a view.
|
|
31
36
|
|
|
32
37
|
```ts
|
|
33
38
|
import { CogniteClient } from "@cognite/sdk";
|
|
@@ -48,58 +53,55 @@ const model = new IndustrialModelClient(client, {
|
|
|
48
53
|
|
|
49
54
|
const { items } = await model.query<{ name: string; description: string }>()({
|
|
50
55
|
viewExternalId: "CogniteAsset",
|
|
51
|
-
select: {
|
|
52
|
-
|
|
56
|
+
select: {
|
|
57
|
+
name: true,
|
|
58
|
+
description: true,
|
|
59
|
+
},
|
|
60
|
+
filters: {
|
|
61
|
+
name: { prefix: "Pump" },
|
|
62
|
+
},
|
|
63
|
+
sort: {
|
|
64
|
+
name: "ascending",
|
|
65
|
+
},
|
|
53
66
|
limit: 10,
|
|
54
67
|
});
|
|
68
|
+
|
|
69
|
+
items[0]?.name;
|
|
55
70
|
```
|
|
56
71
|
|
|
57
|
-
|
|
72
|
+
This is the basic contract:
|
|
58
73
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
| Relations | [Parent/root](#query-assets-with-parent-and-root-relations), [Path](#query-assets-with-their-full-path), [Children](#query-child-assets-reverse-relation), [Edges](#traverse-edge-relations-360-images-on-3d-objects) |
|
|
64
|
-
| Filters | [AND/OR/NOT](#combine-filters-with-and--or--not), [Text search](#search-text-fields), [Nested](#filter-on-related-nodes), [Tags](#filter-assets-by-tags), [Batch IDs](#filter-by-multiple-external-ids) |
|
|
65
|
-
| Select & sort | [Select all scalars](#select-all-scalar-fields), [Multi-field sort](#sort-by-multiple-fields) |
|
|
66
|
-
| Pagination | [Manual cursor loop](#paginate-through-all-assets), [Fetch all pages](#fetch-all-pages-automatically) |
|
|
67
|
-
| Aggregation | [Count by group](#count-assets-by-source-id), [Distinct values](#list-distinct-source-ids), [Numeric aggregates](#average-volume-by-type), [Global count](#count-all-matching-assets) |
|
|
68
|
-
| Advanced | [Custom data model](#use-a-custom-data-model), [Full query](#full-example-assets-equipment-and-filters) |
|
|
74
|
+
1. `viewExternalId` selects the Cognite view.
|
|
75
|
+
2. The generic type describes the fields you want TypeScript to understand.
|
|
76
|
+
3. `select` controls the returned shape.
|
|
77
|
+
4. `filters`, `sort`, `limit`, and `cursor` control the query behavior.
|
|
69
78
|
|
|
70
|
-
|
|
79
|
+
## Define A Model
|
|
71
80
|
|
|
72
|
-
|
|
81
|
+
For scalar-only views, a plain object type is enough:
|
|
73
82
|
|
|
74
83
|
```ts
|
|
75
|
-
|
|
76
|
-
IndustrialModel,
|
|
77
|
-
ModelProps,
|
|
78
|
-
ModelRelations,
|
|
79
|
-
NodeId,
|
|
80
|
-
QueryResultItem,
|
|
81
|
-
} from "industrial-model";
|
|
82
|
-
|
|
83
|
-
type CogniteAssetClass = IndustrialModel<{
|
|
84
|
+
type CogniteAssetClass = {
|
|
84
85
|
name: string;
|
|
85
86
|
code: string;
|
|
86
|
-
}
|
|
87
|
+
};
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
When a view has expandable relations, use `IndustrialModel<TProps, TRelations>`. Put the raw view properties in `TProps`, and put expandable relation result shapes in `TRelations`.
|
|
91
|
+
|
|
92
|
+
```ts
|
|
93
|
+
import type { IndustrialModel, ModelProps, ModelRelations, NodeId } from "industrial-model";
|
|
87
94
|
|
|
88
95
|
type CogniteAsset = IndustrialModel<
|
|
89
96
|
{
|
|
90
97
|
name: string;
|
|
91
98
|
description: string;
|
|
92
99
|
tags: string[];
|
|
93
|
-
aliases: string[];
|
|
94
100
|
sourceId: string;
|
|
95
|
-
sourceCreatedTime: string;
|
|
96
|
-
sourceUpdatedTime: string;
|
|
97
101
|
parent?: NodeId;
|
|
98
102
|
root?: NodeId;
|
|
99
103
|
path: NodeId[];
|
|
100
104
|
assetClass?: NodeId;
|
|
101
|
-
type?: NodeId;
|
|
102
|
-
source?: NodeId;
|
|
103
105
|
},
|
|
104
106
|
{
|
|
105
107
|
parent?: CogniteAsset;
|
|
@@ -109,77 +111,27 @@ type CogniteAsset = IndustrialModel<
|
|
|
109
111
|
}
|
|
110
112
|
>;
|
|
111
113
|
|
|
112
|
-
type CogniteActivity = IndustrialModel<{
|
|
113
|
-
name: string;
|
|
114
|
-
description: string;
|
|
115
|
-
startTime: string;
|
|
116
|
-
endTime: string;
|
|
117
|
-
scheduledStartTime: string;
|
|
118
|
-
scheduledEndTime: string;
|
|
119
|
-
assets: NodeId[];
|
|
120
|
-
equipment: NodeId[];
|
|
121
|
-
timeSeries: NodeId[];
|
|
122
|
-
}>;
|
|
123
|
-
|
|
124
114
|
type CogniteEquipment = IndustrialModel<
|
|
125
115
|
{
|
|
126
116
|
name: string;
|
|
127
|
-
description: string;
|
|
128
117
|
manufacturer: string;
|
|
129
118
|
serialNumber: string;
|
|
130
119
|
tags: string[];
|
|
131
120
|
asset?: NodeId;
|
|
132
|
-
equipmentType?: NodeId;
|
|
133
|
-
source?: NodeId;
|
|
134
121
|
},
|
|
135
122
|
{
|
|
136
123
|
asset?: CogniteAsset;
|
|
137
|
-
activities?: CogniteActivity[];
|
|
138
|
-
}
|
|
139
|
-
>;
|
|
140
|
-
|
|
141
|
-
type CogniteUnit = IndustrialModel<{
|
|
142
|
-
name: string;
|
|
143
|
-
symbol: string;
|
|
144
|
-
quantity: string;
|
|
145
|
-
source: string;
|
|
146
|
-
}>;
|
|
147
|
-
|
|
148
|
-
type CogniteTimeSeries = IndustrialModel<
|
|
149
|
-
{
|
|
150
|
-
name: string;
|
|
151
|
-
description: string;
|
|
152
|
-
isStep: boolean;
|
|
153
|
-
sourceUnit: string;
|
|
154
|
-
unit?: NodeId;
|
|
155
|
-
assets: NodeId[];
|
|
156
|
-
equipment: NodeId[];
|
|
157
|
-
},
|
|
158
|
-
{
|
|
159
|
-
unit?: CogniteUnit;
|
|
160
|
-
}
|
|
161
|
-
>;
|
|
162
|
-
|
|
163
|
-
type Cognite360Image = IndustrialModel<{
|
|
164
|
-
takenAt: string;
|
|
165
|
-
}>;
|
|
166
|
-
|
|
167
|
-
type Cognite3DObject = IndustrialModel<
|
|
168
|
-
{
|
|
169
|
-
name: string;
|
|
170
|
-
description: string;
|
|
171
|
-
},
|
|
172
|
-
{
|
|
173
|
-
images360?: Cognite360Image[];
|
|
174
124
|
}
|
|
175
125
|
>;
|
|
176
126
|
```
|
|
177
127
|
|
|
178
|
-
|
|
128
|
+
The relation metadata is type-only. It lets the SDK infer nested `select` trees and nested filters while Cognite remains the source of truth for the actual view and relation definitions.
|
|
129
|
+
|
|
130
|
+
All examples below use the [Cognite Core Data Model](https://docs.cognite.com/cdf/data_modeling/reference_data_models/cognite_core/), space `cdf_cdm`, version `v1`.
|
|
179
131
|
|
|
180
|
-
|
|
132
|
+
## Query Basics
|
|
181
133
|
|
|
182
|
-
|
|
134
|
+
Start with a single view, select the fields the application needs, then layer on filters and sorting.
|
|
183
135
|
|
|
184
136
|
```ts
|
|
185
137
|
const { items, cursor } = await model.query<CogniteAsset>()({
|
|
@@ -193,32 +145,22 @@ const { items, cursor } = await model.query<CogniteAsset>()({
|
|
|
193
145
|
filters: {
|
|
194
146
|
name: { prefix: "Pump" },
|
|
195
147
|
},
|
|
196
|
-
sort: {
|
|
148
|
+
sort: {
|
|
149
|
+
name: "ascending",
|
|
150
|
+
},
|
|
197
151
|
limit: 100,
|
|
198
152
|
});
|
|
199
153
|
```
|
|
200
154
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
### Query a single asset by externalId
|
|
155
|
+
The returned item type follows the selection:
|
|
204
156
|
|
|
205
157
|
```ts
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
filters: {
|
|
210
|
-
externalId: { eq: "WMT:VAL" },
|
|
211
|
-
},
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
const asset = items[0];
|
|
158
|
+
items[0]?.name; // string
|
|
159
|
+
items[0]?.description; // string
|
|
160
|
+
items[0]?.externalId; // instance metadata is always included
|
|
215
161
|
```
|
|
216
162
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
### Query assets with parent and root relations
|
|
220
|
-
|
|
221
|
-
Traverse up the asset hierarchy — fetch each asset alongside its direct parent and the root of the tree.
|
|
163
|
+
To find one known instance, filter by `externalId`:
|
|
222
164
|
|
|
223
165
|
```ts
|
|
224
166
|
const { items } = await model.query<CogniteAsset>()({
|
|
@@ -226,51 +168,31 @@ const { items } = await model.query<CogniteAsset>()({
|
|
|
226
168
|
select: {
|
|
227
169
|
name: true,
|
|
228
170
|
description: true,
|
|
229
|
-
|
|
230
|
-
name: true,
|
|
231
|
-
description: true,
|
|
232
|
-
parent: {
|
|
233
|
-
name: true,
|
|
234
|
-
},
|
|
235
|
-
},
|
|
236
|
-
root: {
|
|
237
|
-
name: true,
|
|
238
|
-
},
|
|
171
|
+
tags: true,
|
|
239
172
|
},
|
|
240
173
|
filters: {
|
|
241
|
-
|
|
174
|
+
externalId: { eq: "WMT:VAL" },
|
|
242
175
|
},
|
|
243
|
-
limit: 50,
|
|
244
176
|
});
|
|
245
177
|
|
|
246
|
-
const
|
|
178
|
+
const asset = items[0];
|
|
247
179
|
```
|
|
248
180
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
### Query assets with their full path
|
|
252
|
-
|
|
253
|
-
The `path` property is a list of `NodeId` references representing the ancestor chain. Use it to reconstruct breadcrumbs.
|
|
181
|
+
Use `_all` when you want every scalar property from the root view:
|
|
254
182
|
|
|
255
183
|
```ts
|
|
256
184
|
const { items } = await model.query<CogniteAsset>()({
|
|
257
185
|
viewExternalId: "CogniteAsset",
|
|
258
|
-
select: {
|
|
259
|
-
|
|
260
|
-
path: {
|
|
261
|
-
name: true,
|
|
262
|
-
description: true,
|
|
263
|
-
},
|
|
264
|
-
},
|
|
265
|
-
filters: {
|
|
266
|
-
externalId: { eq: "WMT:VAL" },
|
|
267
|
-
},
|
|
186
|
+
select: { _all: true },
|
|
187
|
+
limit: 50,
|
|
268
188
|
});
|
|
269
189
|
```
|
|
270
190
|
|
|
271
|
-
|
|
191
|
+
`_all` includes scalar fields and relation IDs. Add nested selections when you want relation objects instead of `NodeId` references.
|
|
192
|
+
|
|
193
|
+
## Filters And Sorting
|
|
272
194
|
|
|
273
|
-
|
|
195
|
+
Filters are typed from your model. String, number, boolean, date, `NodeId`, and list fields each expose the operators that make sense for that field.
|
|
274
196
|
|
|
275
197
|
```ts
|
|
276
198
|
const { items } = await model.query<CogniteEquipment>()({
|
|
@@ -286,198 +208,93 @@ const { items } = await model.query<CogniteEquipment>()({
|
|
|
286
208
|
asset: { eq: { space: "my-space", externalId: "WMT:VAL" } },
|
|
287
209
|
manufacturer: { exists: true },
|
|
288
210
|
},
|
|
289
|
-
sort: {
|
|
211
|
+
sort: {
|
|
212
|
+
name: "ascending",
|
|
213
|
+
},
|
|
290
214
|
limit: 50,
|
|
291
215
|
});
|
|
292
216
|
```
|
|
293
217
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
### Query time series with their unit
|
|
218
|
+
Combine conditions with `AND`, `OR`, and `NOT`:
|
|
297
219
|
|
|
298
220
|
```ts
|
|
299
|
-
const { items } = await model.query<
|
|
300
|
-
viewExternalId: "
|
|
221
|
+
const { items } = await model.query<CogniteAsset>()({
|
|
222
|
+
viewExternalId: "CogniteAsset",
|
|
301
223
|
select: {
|
|
302
224
|
name: true,
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
sourceUnit: true,
|
|
306
|
-
unit: {
|
|
307
|
-
name: true,
|
|
308
|
-
symbol: true,
|
|
309
|
-
quantity: true,
|
|
310
|
-
},
|
|
225
|
+
tags: true,
|
|
226
|
+
sourceId: true,
|
|
311
227
|
},
|
|
312
228
|
filters: {
|
|
313
|
-
|
|
314
|
-
|
|
229
|
+
OR: [
|
|
230
|
+
{ tags: { containsAny: ["critical"] } },
|
|
231
|
+
{ name: { prefix: "Compressor" } },
|
|
232
|
+
],
|
|
233
|
+
NOT: {
|
|
234
|
+
sourceId: { eq: "legacy-system" },
|
|
235
|
+
},
|
|
315
236
|
},
|
|
316
|
-
limit:
|
|
237
|
+
limit: 100,
|
|
317
238
|
});
|
|
318
239
|
```
|
|
319
240
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
### Query activities in a time window
|
|
241
|
+
List fields support `containsAny` and `containsAll`:
|
|
323
242
|
|
|
324
243
|
```ts
|
|
325
|
-
const
|
|
326
|
-
viewExternalId: "
|
|
244
|
+
const critical = await model.query<CogniteAsset>()({
|
|
245
|
+
viewExternalId: "CogniteAsset",
|
|
327
246
|
select: {
|
|
328
247
|
name: true,
|
|
329
|
-
|
|
330
|
-
startTime: true,
|
|
331
|
-
endTime: true,
|
|
332
|
-
scheduledStartTime: true,
|
|
333
|
-
scheduledEndTime: true,
|
|
248
|
+
tags: true,
|
|
334
249
|
},
|
|
335
250
|
filters: {
|
|
336
|
-
|
|
251
|
+
tags: { containsAny: ["critical", "safety"] },
|
|
337
252
|
},
|
|
338
|
-
|
|
339
|
-
limit: 500,
|
|
253
|
+
limit: 100,
|
|
340
254
|
});
|
|
341
|
-
```
|
|
342
|
-
|
|
343
|
-
---
|
|
344
255
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
Fetch assets that are either tagged `"critical"` or have a name starting with `"Compressor"`, but exclude those from source `"legacy-system"`.
|
|
348
|
-
|
|
349
|
-
```ts
|
|
350
|
-
const { items } = await model.query<CogniteAsset>()({
|
|
256
|
+
const fullyTagged = await model.query<CogniteAsset>()({
|
|
351
257
|
viewExternalId: "CogniteAsset",
|
|
352
|
-
select: {
|
|
258
|
+
select: {
|
|
259
|
+
name: true,
|
|
260
|
+
tags: true,
|
|
261
|
+
},
|
|
353
262
|
filters: {
|
|
354
|
-
|
|
355
|
-
{ tags: { containsAny: ["critical"] } },
|
|
356
|
-
{ name: { prefix: "Compressor" } },
|
|
357
|
-
],
|
|
358
|
-
NOT: { sourceId: { eq: "legacy-system" } },
|
|
263
|
+
tags: { containsAll: ["production", "verified"] },
|
|
359
264
|
},
|
|
360
265
|
limit: 100,
|
|
361
266
|
});
|
|
362
267
|
```
|
|
363
268
|
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
### Paginate through all assets
|
|
367
|
-
|
|
368
|
-
```ts
|
|
369
|
-
let cursor: string | null = null;
|
|
370
|
-
const allAssets: QueryResultItem<CogniteAsset, { name: true; description: true }>[] = [];
|
|
371
|
-
|
|
372
|
-
do {
|
|
373
|
-
const result = await model.query<CogniteAsset>()({
|
|
374
|
-
viewExternalId: "CogniteAsset",
|
|
375
|
-
select: { name: true, description: true },
|
|
376
|
-
limit: 1000,
|
|
377
|
-
cursor,
|
|
378
|
-
});
|
|
379
|
-
|
|
380
|
-
allAssets.push(...result.items);
|
|
381
|
-
cursor = result.cursor;
|
|
382
|
-
} while (cursor !== null);
|
|
383
|
-
|
|
384
|
-
console.log(`Total assets: ${allAssets.length}`);
|
|
385
|
-
```
|
|
386
|
-
|
|
387
|
-
---
|
|
388
|
-
|
|
389
|
-
### Fetch all pages automatically
|
|
390
|
-
|
|
391
|
-
Pass `limit: -1` to follow root-view cursors until every page is loaded. The SDK issues multiple `instances.query` calls (1000 items per page by default). The returned `cursor` is always `null`.
|
|
392
|
-
|
|
393
|
-
```ts
|
|
394
|
-
const { items } = await model.query<CogniteAsset>()({
|
|
395
|
-
viewExternalId: "CogniteAsset",
|
|
396
|
-
select: { name: true, description: true },
|
|
397
|
-
filters: { tags: { containsAny: ["production"] } },
|
|
398
|
-
limit: -1,
|
|
399
|
-
});
|
|
400
|
-
|
|
401
|
-
console.log(`Loaded ${items.length} assets across all pages`);
|
|
402
|
-
```
|
|
403
|
-
|
|
404
|
-
---
|
|
405
|
-
|
|
406
|
-
### Select all scalar fields
|
|
407
|
-
|
|
408
|
-
Use `_all` to include every scalar property on the view without listing them individually. Relation fields are returned as `NodeId` references but are not expanded — add nested `select` blocks when you need related data.
|
|
409
|
-
|
|
410
|
-
```ts
|
|
411
|
-
const { items } = await model.query<CogniteAsset>()({
|
|
412
|
-
viewExternalId: "CogniteAsset",
|
|
413
|
-
select: { _all: true },
|
|
414
|
-
limit: 50,
|
|
415
|
-
});
|
|
416
|
-
|
|
417
|
-
// items[0] includes name, description, tags, parent (as NodeId), etc.
|
|
418
|
-
```
|
|
419
|
-
|
|
420
|
-
Combine `_all` with explicit relation expansion:
|
|
269
|
+
Sort clauses apply to primitive fields on the root view, including node metadata such as `externalId`.
|
|
421
270
|
|
|
422
271
|
```ts
|
|
423
272
|
const { items } = await model.query<CogniteAsset>()({
|
|
424
273
|
viewExternalId: "CogniteAsset",
|
|
425
274
|
select: {
|
|
426
|
-
|
|
427
|
-
|
|
275
|
+
name: true,
|
|
276
|
+
sourceId: true,
|
|
428
277
|
},
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
---
|
|
434
|
-
|
|
435
|
-
### Filter by multiple external IDs
|
|
436
|
-
|
|
437
|
-
```ts
|
|
438
|
-
const { items } = await model.query<CogniteAsset>()({
|
|
439
|
-
viewExternalId: "CogniteAsset",
|
|
440
|
-
select: { name: true, description: true },
|
|
441
|
-
filters: {
|
|
442
|
-
externalId: {
|
|
443
|
-
in: ["WMT:VAL", "WMT:PUMP-01", "WMT:PUMP-02"],
|
|
444
|
-
},
|
|
278
|
+
sort: {
|
|
279
|
+
name: "ascending",
|
|
280
|
+
externalId: "descending",
|
|
445
281
|
},
|
|
446
|
-
});
|
|
447
|
-
```
|
|
448
|
-
|
|
449
|
-
---
|
|
450
|
-
|
|
451
|
-
### Filter assets by tags
|
|
452
|
-
|
|
453
|
-
```ts
|
|
454
|
-
// Match assets that have at least one of these tags
|
|
455
|
-
const critical = await model.query<CogniteAsset>()({
|
|
456
|
-
viewExternalId: "CogniteAsset",
|
|
457
|
-
select: { name: true, tags: true },
|
|
458
|
-
filters: { tags: { containsAny: ["critical", "safety"] } },
|
|
459
|
-
limit: 100,
|
|
460
|
-
});
|
|
461
|
-
|
|
462
|
-
// Match assets that must have every tag
|
|
463
|
-
const fullyTagged = await model.query<CogniteAsset>()({
|
|
464
|
-
viewExternalId: "CogniteAsset",
|
|
465
|
-
select: { name: true, tags: true },
|
|
466
|
-
filters: { tags: { containsAll: ["production", "verified"] } },
|
|
467
282
|
limit: 100,
|
|
468
283
|
});
|
|
469
284
|
```
|
|
470
285
|
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
### Search text fields
|
|
286
|
+
## Text Search
|
|
474
287
|
|
|
475
|
-
Use `search` on text properties and string-list text properties when you want
|
|
288
|
+
Use `search` on Cognite text properties and string-list text properties when you want full-text matching instead of exact or prefix matching. The optional `operator` is passed to Cognite search and defaults to `"OR"`.
|
|
476
289
|
|
|
477
290
|
```ts
|
|
478
291
|
const { items } = await model.query<CogniteAsset>()({
|
|
479
292
|
viewExternalId: "CogniteAsset",
|
|
480
|
-
select: {
|
|
293
|
+
select: {
|
|
294
|
+
name: true,
|
|
295
|
+
description: true,
|
|
296
|
+
tags: true,
|
|
297
|
+
},
|
|
481
298
|
filters: {
|
|
482
299
|
name: { search: { query: "root pump", operator: "AND" } },
|
|
483
300
|
tags: { search: { query: "critical" } },
|
|
@@ -486,12 +303,15 @@ const { items } = await model.query<CogniteAsset>()({
|
|
|
486
303
|
});
|
|
487
304
|
```
|
|
488
305
|
|
|
489
|
-
Search filters can be combined with
|
|
306
|
+
Search filters can be combined with regular operators. The SDK first calls Cognite `instances.search`, maps the matched nodes to instance references, and then applies those references to the query or aggregate request.
|
|
490
307
|
|
|
491
308
|
```ts
|
|
492
309
|
const pumps = await model.query<CogniteAsset>()({
|
|
493
310
|
viewExternalId: "CogniteAsset",
|
|
494
|
-
select: {
|
|
311
|
+
select: {
|
|
312
|
+
name: true,
|
|
313
|
+
sourceId: true,
|
|
314
|
+
},
|
|
495
315
|
filters: {
|
|
496
316
|
name: {
|
|
497
317
|
prefix: "Pump",
|
|
@@ -502,72 +322,108 @@ const pumps = await model.query<CogniteAsset>()({
|
|
|
502
322
|
});
|
|
503
323
|
```
|
|
504
324
|
|
|
505
|
-
|
|
325
|
+
## Relations
|
|
326
|
+
|
|
327
|
+
The same `select` object that selects scalar fields can expand relations. Direct relations move outward from the current node.
|
|
506
328
|
|
|
507
329
|
```ts
|
|
508
|
-
const { items } = await model.
|
|
330
|
+
const { items } = await model.query<CogniteAsset>()({
|
|
509
331
|
viewExternalId: "CogniteAsset",
|
|
510
|
-
|
|
332
|
+
select: {
|
|
333
|
+
name: true,
|
|
334
|
+
parent: {
|
|
335
|
+
name: true,
|
|
336
|
+
description: true,
|
|
337
|
+
parent: {
|
|
338
|
+
name: true,
|
|
339
|
+
},
|
|
340
|
+
},
|
|
341
|
+
root: {
|
|
342
|
+
name: true,
|
|
343
|
+
},
|
|
344
|
+
},
|
|
511
345
|
filters: {
|
|
512
|
-
name: {
|
|
346
|
+
name: { prefix: "Pump" },
|
|
513
347
|
},
|
|
348
|
+
limit: 50,
|
|
514
349
|
});
|
|
515
|
-
```
|
|
516
350
|
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
### Filter on related nodes
|
|
351
|
+
const firstParentName = items[0]?.parent?.name;
|
|
352
|
+
```
|
|
520
353
|
|
|
521
|
-
|
|
354
|
+
List relations work the same way. For example, `path` can be expanded into asset objects for breadcrumb-style views.
|
|
522
355
|
|
|
523
356
|
```ts
|
|
524
|
-
// Assets whose parent is named "Site Root"
|
|
525
357
|
const { items } = await model.query<CogniteAsset>()({
|
|
526
358
|
viewExternalId: "CogniteAsset",
|
|
527
|
-
select: {
|
|
359
|
+
select: {
|
|
360
|
+
name: true,
|
|
361
|
+
path: {
|
|
362
|
+
name: true,
|
|
363
|
+
description: true,
|
|
364
|
+
},
|
|
365
|
+
},
|
|
528
366
|
filters: {
|
|
529
|
-
|
|
367
|
+
externalId: { eq: "WMT:VAL" },
|
|
530
368
|
},
|
|
531
|
-
limit: 50,
|
|
532
369
|
});
|
|
370
|
+
```
|
|
533
371
|
|
|
534
|
-
|
|
535
|
-
|
|
372
|
+
Nested relation filters let you filter the root view based on related nodes.
|
|
373
|
+
|
|
374
|
+
```ts
|
|
375
|
+
const { items } = await model.query<CogniteAsset>()({
|
|
536
376
|
viewExternalId: "CogniteAsset",
|
|
537
377
|
select: {
|
|
538
378
|
name: true,
|
|
539
|
-
parent: {
|
|
379
|
+
parent: {
|
|
380
|
+
name: true,
|
|
381
|
+
},
|
|
540
382
|
},
|
|
541
383
|
filters: {
|
|
542
|
-
parent: {
|
|
384
|
+
parent: {
|
|
385
|
+
name: { eq: "Site Root" },
|
|
386
|
+
},
|
|
543
387
|
},
|
|
544
388
|
limit: 50,
|
|
545
389
|
});
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
You can keep moving through the graph:
|
|
546
393
|
|
|
547
|
-
|
|
548
|
-
const
|
|
394
|
+
```ts
|
|
395
|
+
const pumpsByClass = await model.query<CogniteAsset>()({
|
|
549
396
|
viewExternalId: "CogniteAsset",
|
|
550
|
-
select: {
|
|
397
|
+
select: {
|
|
398
|
+
name: true,
|
|
399
|
+
parent: {
|
|
400
|
+
assetClass: {
|
|
401
|
+
name: true,
|
|
402
|
+
code: true,
|
|
403
|
+
},
|
|
404
|
+
},
|
|
405
|
+
},
|
|
551
406
|
filters: {
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
407
|
+
parent: {
|
|
408
|
+
assetClass: {
|
|
409
|
+
code: { eq: "PUMP" },
|
|
410
|
+
},
|
|
411
|
+
},
|
|
556
412
|
},
|
|
557
|
-
limit:
|
|
413
|
+
limit: 50,
|
|
558
414
|
});
|
|
559
415
|
```
|
|
560
416
|
|
|
561
|
-
|
|
417
|
+
### Reverse Relations
|
|
562
418
|
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
Declare reverse relations in the `IndustrialModel<TProps, TRelations>` metadata. The library resolves the correct traversal direction from your data model.
|
|
419
|
+
Declare reverse relations in `IndustrialModel<TProps, TRelations>`. The SDK resolves the traversal direction from the Cognite data model.
|
|
566
420
|
|
|
567
421
|
```ts
|
|
568
422
|
type AssetWithChildren = IndustrialModel<
|
|
569
423
|
ModelProps<CogniteAsset>,
|
|
570
|
-
ModelRelations<CogniteAsset> & {
|
|
424
|
+
ModelRelations<CogniteAsset> & {
|
|
425
|
+
children?: CogniteAsset[];
|
|
426
|
+
}
|
|
571
427
|
>;
|
|
572
428
|
|
|
573
429
|
const { items } = await model.query<AssetWithChildren>()({
|
|
@@ -585,18 +441,32 @@ const { items } = await model.query<AssetWithChildren>()({
|
|
|
585
441
|
});
|
|
586
442
|
```
|
|
587
443
|
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
### Traverse edge relations (360 images on 3D objects)
|
|
444
|
+
### Edge Relations
|
|
591
445
|
|
|
592
|
-
Some relations are modeled as edges rather than direct node
|
|
446
|
+
Some relations are modeled as edges rather than direct node references. Select them with the same relation syntax.
|
|
593
447
|
|
|
594
448
|
```ts
|
|
449
|
+
type Cognite360Image = IndustrialModel<{
|
|
450
|
+
takenAt: string;
|
|
451
|
+
}>;
|
|
452
|
+
|
|
453
|
+
type Cognite3DObject = IndustrialModel<
|
|
454
|
+
{
|
|
455
|
+
name: string;
|
|
456
|
+
description: string;
|
|
457
|
+
},
|
|
458
|
+
{
|
|
459
|
+
images360?: Cognite360Image[];
|
|
460
|
+
}
|
|
461
|
+
>;
|
|
462
|
+
|
|
595
463
|
const { items } = await model.query<Cognite3DObject>()({
|
|
596
464
|
viewExternalId: "Cognite3DObject",
|
|
597
465
|
select: {
|
|
598
466
|
name: true,
|
|
599
|
-
images360: {
|
|
467
|
+
images360: {
|
|
468
|
+
takenAt: true,
|
|
469
|
+
},
|
|
600
470
|
},
|
|
601
471
|
filters: {
|
|
602
472
|
name: { prefix: "Tank" },
|
|
@@ -605,120 +475,176 @@ const { items } = await model.query<Cognite3DObject>()({
|
|
|
605
475
|
});
|
|
606
476
|
```
|
|
607
477
|
|
|
608
|
-
|
|
478
|
+
## Pagination
|
|
479
|
+
|
|
480
|
+
`query()` returns a root cursor when more root-view items are available.
|
|
481
|
+
|
|
482
|
+
```ts
|
|
483
|
+
import type { QueryResultItem } from "industrial-model";
|
|
484
|
+
|
|
485
|
+
let cursor: string | null = null;
|
|
486
|
+
const allAssets: QueryResultItem<CogniteAsset, { name: true; description: true }>[] = [];
|
|
487
|
+
|
|
488
|
+
do {
|
|
489
|
+
const result = await model.query<CogniteAsset>()({
|
|
490
|
+
viewExternalId: "CogniteAsset",
|
|
491
|
+
select: {
|
|
492
|
+
name: true,
|
|
493
|
+
description: true,
|
|
494
|
+
},
|
|
495
|
+
limit: 1000,
|
|
496
|
+
cursor,
|
|
497
|
+
});
|
|
609
498
|
|
|
610
|
-
|
|
499
|
+
allAssets.push(...result.items);
|
|
500
|
+
cursor = result.cursor;
|
|
501
|
+
} while (cursor !== null);
|
|
502
|
+
```
|
|
611
503
|
|
|
612
|
-
|
|
504
|
+
Pass `limit: -1` when you want the SDK to follow all root cursors automatically. The SDK issues multiple `instances.query` calls, using 1000 root items per page by default, and returns `cursor: null`.
|
|
613
505
|
|
|
614
506
|
```ts
|
|
615
507
|
const { items } = await model.query<CogniteAsset>()({
|
|
616
508
|
viewExternalId: "CogniteAsset",
|
|
617
|
-
select: {
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
externalId: "descending",
|
|
509
|
+
select: {
|
|
510
|
+
name: true,
|
|
511
|
+
description: true,
|
|
621
512
|
},
|
|
622
|
-
|
|
513
|
+
filters: {
|
|
514
|
+
tags: { containsAny: ["production"] },
|
|
515
|
+
},
|
|
516
|
+
limit: -1,
|
|
623
517
|
});
|
|
624
518
|
```
|
|
625
519
|
|
|
626
|
-
|
|
520
|
+
Expanded relations use internal pagination as well. When a nested relation query reaches the internal page size, the client follows dependency cursors for up to 3 additional rounds.
|
|
627
521
|
|
|
628
|
-
|
|
522
|
+
## Upsert
|
|
629
523
|
|
|
630
|
-
|
|
524
|
+
Use `upsert()` to create or patch nodes with the same model shape you use for queries. Each item must include `space` and `externalId`; all other fields are optional and only the fields you pass are updated.
|
|
631
525
|
|
|
632
526
|
```ts
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
527
|
+
await model.upsert<CogniteAsset>()({
|
|
528
|
+
viewExternalId: "CogniteAsset",
|
|
529
|
+
items: [
|
|
530
|
+
{
|
|
531
|
+
space: "asset-space",
|
|
532
|
+
externalId: "pump-1",
|
|
533
|
+
name: "Pump 1",
|
|
534
|
+
parent: { space: "asset-space", externalId: "root" },
|
|
535
|
+
},
|
|
536
|
+
],
|
|
637
537
|
});
|
|
538
|
+
```
|
|
638
539
|
|
|
639
|
-
|
|
640
|
-
name: string;
|
|
641
|
-
code: string;
|
|
642
|
-
site?: NodeId;
|
|
643
|
-
}>;
|
|
540
|
+
Direct relations are written as `NodeId` values. Reverse direct relations are written by patching the target nodes through the relation field defined in Cognite. For example, writing `children` on an asset updates each child asset's `parent` reference.
|
|
644
541
|
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
542
|
+
```ts
|
|
543
|
+
await model.upsert<CogniteAsset>()({
|
|
544
|
+
viewExternalId: "CogniteAsset",
|
|
545
|
+
items: [
|
|
546
|
+
{
|
|
547
|
+
space: "asset-space",
|
|
548
|
+
externalId: "parent-asset",
|
|
549
|
+
children: [{ space: "asset-space", externalId: "child-1" }],
|
|
550
|
+
},
|
|
551
|
+
],
|
|
650
552
|
});
|
|
651
553
|
```
|
|
652
554
|
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
### Full example: assets, equipment, and filters
|
|
656
|
-
|
|
657
|
-
A single query combining nested selects, nested filters, sorting, and pagination.
|
|
555
|
+
Edge-backed relations need an edge ID. Provide `onEdgeCreation` for every edge connection property you write. The callback receives normalized `startNode`, `endNode`, and `edgeType` values after the SDK has applied the relation direction from the view metadata.
|
|
658
556
|
|
|
659
557
|
```ts
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
select: {
|
|
668
|
-
name: true,
|
|
669
|
-
description: true,
|
|
670
|
-
tags: true,
|
|
671
|
-
parent: {
|
|
672
|
-
name: true,
|
|
673
|
-
assetClass: { name: true, code: true },
|
|
558
|
+
await model.upsert<Cognite3DObject>()({
|
|
559
|
+
viewExternalId: "Cognite3DObject",
|
|
560
|
+
items: [
|
|
561
|
+
{
|
|
562
|
+
space: "object-space",
|
|
563
|
+
externalId: "object-1",
|
|
564
|
+
images360: [{ space: "image-space", externalId: "image-1" }],
|
|
674
565
|
},
|
|
566
|
+
],
|
|
567
|
+
onEdgeCreation: {
|
|
568
|
+
images360: ({ startNode, endNode, edgeType }) => ({
|
|
569
|
+
space: startNode.space,
|
|
570
|
+
externalId: `${startNode.externalId}:${edgeType.externalId}:${endNode.externalId}`,
|
|
571
|
+
}),
|
|
675
572
|
},
|
|
676
|
-
filters: {
|
|
677
|
-
name: { prefix: "WMT" },
|
|
678
|
-
parent: { name: { exists: true } },
|
|
679
|
-
OR: [
|
|
680
|
-
{ tags: { containsAny: ["critical"] } },
|
|
681
|
-
{ sourceId: { eq: "sap" } },
|
|
682
|
-
],
|
|
683
|
-
},
|
|
684
|
-
sort: { name: "ascending" },
|
|
685
|
-
limit: 25,
|
|
686
|
-
cursor: null,
|
|
687
573
|
});
|
|
574
|
+
```
|
|
688
575
|
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
576
|
+
`edgeMode` controls how edge connection properties are applied:
|
|
577
|
+
|
|
578
|
+
| Mode | Behavior |
|
|
579
|
+
| --- | --- |
|
|
580
|
+
| `"append"` | Default. Creates the generated edges and leaves existing edges untouched. |
|
|
581
|
+
| `"replace"` | Queries existing edges for the provided edge connection fields, deletes edges that were not generated by the current upsert, then applies the new edges. |
|
|
582
|
+
|
|
583
|
+
To clear an edge connection for a node, include the property with an empty array and use `edgeMode: "replace"`:
|
|
584
|
+
|
|
585
|
+
```ts
|
|
586
|
+
await model.upsert<Cognite3DObject>()({
|
|
587
|
+
viewExternalId: "Cognite3DObject",
|
|
588
|
+
edgeMode: "replace",
|
|
589
|
+
items: [
|
|
590
|
+
{
|
|
591
|
+
space: "object-space",
|
|
592
|
+
externalId: "object-1",
|
|
593
|
+
images360: [],
|
|
702
594
|
},
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
cursor,
|
|
706
|
-
});
|
|
707
|
-
}
|
|
595
|
+
],
|
|
596
|
+
});
|
|
708
597
|
```
|
|
709
598
|
|
|
710
|
-
|
|
599
|
+
This deletes existing `images360` edges for `object-1`. Other edge connection fields on the same node are not touched, and omitting `images360` entirely leaves its existing edges unchanged.
|
|
600
|
+
|
|
601
|
+
Use `replace: true` when you want Cognite apply replace semantics for container-backed node properties.
|
|
602
|
+
|
|
603
|
+
Important constraints:
|
|
711
604
|
|
|
712
|
-
|
|
605
|
+
- Relation fields accept only `NodeId` or `NodeId[]` references. Nested node mutation is intentionally not supported.
|
|
606
|
+
- Unknown fields are rejected before Cognite is called.
|
|
607
|
+
- Edge connection fields require `onEdgeCreation.<property>` only when the submitted array contains edges to create.
|
|
608
|
+
- Cognite apply requests are limited to 1000 writes/deletes per call. You can still pass more than 1000 upsert items or edge references; the SDK follows paginated edge-replacement queries and splits large apply payloads into multiple Cognite calls.
|
|
609
|
+
- `edgeMode: "replace"` only replaces edge connection fields included in the submitted items.
|
|
713
610
|
|
|
714
|
-
|
|
611
|
+
## Delete
|
|
612
|
+
|
|
613
|
+
Use `delete()` when you only need to delete nodes by identity. The method accepts an array of values with `space` and `externalId`; any extra fields are ignored.
|
|
614
|
+
|
|
615
|
+
```ts
|
|
616
|
+
await model.delete([
|
|
617
|
+
{ space: "asset-space", externalId: "pump-1" },
|
|
618
|
+
{ space: "asset-space", externalId: "pump-2", name: "Pump 2" },
|
|
619
|
+
]);
|
|
620
|
+
```
|
|
621
|
+
|
|
622
|
+
The delete operation is view-independent, so it does not require `viewExternalId` and is also available directly on `CogniteCoreClient`.
|
|
623
|
+
|
|
624
|
+
```ts
|
|
625
|
+
await core.delete([{ space: "asset-space", externalId: "pump-1" }]);
|
|
626
|
+
```
|
|
627
|
+
|
|
628
|
+
Deletes are sent through Cognite apply. When more than 1000 nodes are provided, the SDK splits them into multiple Cognite calls.
|
|
629
|
+
|
|
630
|
+
## Aggregation
|
|
631
|
+
|
|
632
|
+
Use `aggregate()` when you need grouped counts, distinct values, or numeric summaries without loading every instance.
|
|
633
|
+
|
|
634
|
+
Group and count assets by `sourceId`:
|
|
715
635
|
|
|
716
636
|
```ts
|
|
717
637
|
const { items } = await model.aggregate<CogniteAsset>()({
|
|
718
638
|
viewExternalId: "CogniteAsset",
|
|
719
|
-
groupBy: {
|
|
720
|
-
|
|
721
|
-
|
|
639
|
+
groupBy: {
|
|
640
|
+
sourceId: true,
|
|
641
|
+
},
|
|
642
|
+
aggregate: {
|
|
643
|
+
count: {},
|
|
644
|
+
},
|
|
645
|
+
filters: {
|
|
646
|
+
name: { prefix: "WMT" },
|
|
647
|
+
},
|
|
722
648
|
});
|
|
723
649
|
|
|
724
650
|
for (const row of items) {
|
|
@@ -726,37 +652,36 @@ for (const row of items) {
|
|
|
726
652
|
}
|
|
727
653
|
```
|
|
728
654
|
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
### List distinct source IDs
|
|
732
|
-
|
|
733
|
-
Omit `aggregate` to return unique combinations of the `groupBy` fields (up to 1000 groups).
|
|
655
|
+
Omit `aggregate` to list distinct values for grouped fields:
|
|
734
656
|
|
|
735
657
|
```ts
|
|
736
658
|
const { items } = await model.aggregate<CogniteAsset>()({
|
|
737
659
|
viewExternalId: "CogniteAsset",
|
|
738
|
-
groupBy: {
|
|
660
|
+
groupBy: {
|
|
661
|
+
sourceId: true,
|
|
662
|
+
},
|
|
739
663
|
});
|
|
740
664
|
|
|
741
665
|
const sourceIds = items.map((row) => row.group?.sourceId);
|
|
742
666
|
```
|
|
743
667
|
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
### Average volume by type
|
|
747
|
-
|
|
748
|
-
Use `avg`, `min`, `max`, or `sum` on numeric view properties. Only one aggregate operation per call.
|
|
668
|
+
Use `avg`, `min`, `max`, or `sum` on numeric properties:
|
|
749
669
|
|
|
750
670
|
```ts
|
|
751
671
|
type PointCloudVolume = IndustrialModel<{
|
|
752
672
|
volume: number;
|
|
753
673
|
volumeType: string;
|
|
674
|
+
object3D?: NodeId;
|
|
754
675
|
}>;
|
|
755
676
|
|
|
756
677
|
const { items } = await model.aggregate<PointCloudVolume>()({
|
|
757
678
|
viewExternalId: "CognitePointCloudVolume",
|
|
758
|
-
groupBy: {
|
|
759
|
-
|
|
679
|
+
groupBy: {
|
|
680
|
+
volumeType: true,
|
|
681
|
+
},
|
|
682
|
+
aggregate: {
|
|
683
|
+
avg: "volume",
|
|
684
|
+
},
|
|
760
685
|
});
|
|
761
686
|
|
|
762
687
|
items[0]?.group?.volumeType;
|
|
@@ -764,219 +689,472 @@ items[0]?.aggregate?.property; // "volume"
|
|
|
764
689
|
items[0]?.aggregate?.value;
|
|
765
690
|
```
|
|
766
691
|
|
|
767
|
-
|
|
692
|
+
Count all rows matching a filter:
|
|
768
693
|
|
|
769
694
|
```ts
|
|
770
|
-
await model.aggregate<
|
|
771
|
-
viewExternalId: "
|
|
772
|
-
aggregate: {
|
|
695
|
+
const { items } = await model.aggregate<CogniteAsset>()({
|
|
696
|
+
viewExternalId: "CogniteAsset",
|
|
697
|
+
aggregate: {
|
|
698
|
+
count: {},
|
|
699
|
+
},
|
|
700
|
+
filters: {
|
|
701
|
+
OR: [{ tags: { containsAny: ["critical"] } }, { sourceId: { eq: "sap" } }],
|
|
702
|
+
},
|
|
773
703
|
});
|
|
774
704
|
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
705
|
+
items[0]?.aggregate?.value;
|
|
706
|
+
```
|
|
707
|
+
|
|
708
|
+
Group by a direct relation when you need relation IDs in the result:
|
|
779
709
|
|
|
780
|
-
|
|
710
|
+
```ts
|
|
711
|
+
const { items } = await model.aggregate<PointCloudVolume>()({
|
|
781
712
|
viewExternalId: "CognitePointCloudVolume",
|
|
782
|
-
|
|
713
|
+
groupBy: {
|
|
714
|
+
object3D: true,
|
|
715
|
+
},
|
|
716
|
+
aggregate: {
|
|
717
|
+
sum: "volume",
|
|
718
|
+
},
|
|
783
719
|
});
|
|
784
|
-
```
|
|
785
720
|
|
|
786
|
-
|
|
721
|
+
items[0]?.group?.object3D?.externalId;
|
|
722
|
+
```
|
|
787
723
|
|
|
788
|
-
|
|
724
|
+
Text search filters are also supported in aggregations:
|
|
789
725
|
|
|
790
726
|
```ts
|
|
791
727
|
const { items } = await model.aggregate<CogniteAsset>()({
|
|
792
728
|
viewExternalId: "CogniteAsset",
|
|
793
|
-
aggregate: {
|
|
729
|
+
aggregate: {
|
|
730
|
+
count: {},
|
|
731
|
+
},
|
|
732
|
+
filters: {
|
|
733
|
+
name: { search: { query: "compressor seal" } },
|
|
734
|
+
},
|
|
794
735
|
});
|
|
795
|
-
|
|
796
|
-
items[0]?.aggregate?.property; // "name"
|
|
797
|
-
items[0]?.aggregate?.value;
|
|
798
736
|
```
|
|
799
737
|
|
|
800
|
-
|
|
738
|
+
## Runtime Validation
|
|
801
739
|
|
|
802
|
-
|
|
740
|
+
By default, the SDK validates query inputs against the loaded Cognite view metadata before building the request. Query results are mapped without parsing each returned item.
|
|
803
741
|
|
|
804
|
-
|
|
742
|
+
Enable `validateResults` when you also want result parsing through Zod schemas derived from Cognite view metadata:
|
|
805
743
|
|
|
806
744
|
```ts
|
|
807
|
-
const
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
745
|
+
const model = new IndustrialModelClient(
|
|
746
|
+
client,
|
|
747
|
+
{
|
|
748
|
+
space: "cdf_cdm",
|
|
749
|
+
externalId: "CogniteCore",
|
|
750
|
+
version: "v1",
|
|
812
751
|
},
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
752
|
+
{
|
|
753
|
+
validateResults: true,
|
|
754
|
+
},
|
|
755
|
+
);
|
|
816
756
|
```
|
|
817
757
|
|
|
818
|
-
|
|
758
|
+
When result validation is enabled, Cognite `date` and `timestamp` view properties are converted to JavaScript `Date` objects. Without it, result values are returned as Cognite provides them, usually ISO strings for timestamps.
|
|
819
759
|
|
|
820
|
-
|
|
760
|
+
## Cognite Core Client
|
|
821
761
|
|
|
822
|
-
|
|
762
|
+
For applications working with the Cognite Core Data Model (`cdf_cdm/CogniteCore/v1`), use `CogniteCoreClient` instead of `IndustrialModelClient`. It pre-configures the data model, bundles all view type definitions, and moves the view name to the first positional argument so TypeScript can infer the model type without a generic annotation.
|
|
823
763
|
|
|
824
764
|
```ts
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
object3D?: NodeId;
|
|
828
|
-
}>;
|
|
765
|
+
import { CogniteClient } from "@cognite/sdk";
|
|
766
|
+
import { CogniteCoreClient } from "industrial-model/cognite-core";
|
|
829
767
|
|
|
830
|
-
const
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
768
|
+
const client = new CogniteClient({ ... });
|
|
769
|
+
const core = new CogniteCoreClient(client);
|
|
770
|
+
```
|
|
771
|
+
|
|
772
|
+
Query any Cognite Core view by passing its name to `query()`:
|
|
773
|
+
|
|
774
|
+
```ts
|
|
775
|
+
const { items } = await core.query("CogniteAsset")({
|
|
776
|
+
select: {
|
|
777
|
+
name: true,
|
|
778
|
+
description: true,
|
|
779
|
+
parent: { name: true },
|
|
780
|
+
},
|
|
781
|
+
filters: {
|
|
782
|
+
name: { prefix: "Pump" },
|
|
783
|
+
},
|
|
784
|
+
limit: 50,
|
|
834
785
|
});
|
|
835
786
|
|
|
836
|
-
items[0]?.
|
|
787
|
+
items[0]?.name; // string | undefined
|
|
788
|
+
items[0]?.parent?.name; // string | undefined
|
|
837
789
|
```
|
|
838
790
|
|
|
839
|
-
|
|
791
|
+
The view name drives TypeScript inference — no generic annotation is needed. All filters, `select` fields, and nested relation selections are type-checked against the bundled view definition. Every feature available on `IndustrialModelClient` — text search, pagination, `limit: -1`, nested filters, and relation traversal — works identically.
|
|
840
792
|
|
|
841
|
-
|
|
793
|
+
Aggregations use the same positional-view-name pattern:
|
|
842
794
|
|
|
843
|
-
|
|
795
|
+
```ts
|
|
796
|
+
const { items } = await core.aggregate("CogniteEquipment")({
|
|
797
|
+
groupBy: { manufacturer: true },
|
|
798
|
+
aggregate: { count: {} },
|
|
799
|
+
filters: {
|
|
800
|
+
equipmentType: { exists: true },
|
|
801
|
+
},
|
|
802
|
+
});
|
|
844
803
|
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
| `IndustrialModel`, `ModelProps`, `ModelRelations` | Type helpers for models and relations |
|
|
849
|
-
| `NodeId`, `DataModelId` | Instance and data-model identifiers |
|
|
850
|
-
| `QueryOptions`, `QuerySelect`, `WhereInput`, `SortInput` | Query input types |
|
|
851
|
-
| `QueryResult`, `QueryResultItem`, `QueryResultMetadata` | Query output types |
|
|
852
|
-
| `AggregateOptions`, `AggregateGroupBy`, `AggregateDefinition` | Aggregate input types |
|
|
853
|
-
| `AggregateResult`, `AggregateResultItem`, `GroupByKey` | Aggregate output types |
|
|
854
|
-
| `buildViewSchema`, `nodeIdSchema` | Zod schemas built from Cognite view metadata |
|
|
855
|
-
| `SortDirection` | `"ascending"` \| `"descending"` |
|
|
804
|
+
items[0]?.group?.manufacturer;
|
|
805
|
+
items[0]?.aggregate?.value;
|
|
806
|
+
```
|
|
856
807
|
|
|
857
|
-
|
|
808
|
+
Upserts use the same pattern and infer the item shape from the view name:
|
|
858
809
|
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
810
|
+
```ts
|
|
811
|
+
await core.upsert("CogniteAsset")({
|
|
812
|
+
items: [
|
|
813
|
+
{
|
|
814
|
+
space: "asset-space",
|
|
815
|
+
externalId: "pump-1",
|
|
816
|
+
name: "Pump 1",
|
|
817
|
+
parent: { space: "asset-space", externalId: "root" },
|
|
818
|
+
},
|
|
819
|
+
],
|
|
820
|
+
});
|
|
821
|
+
```
|
|
822
|
+
|
|
823
|
+
Deletes are view-independent:
|
|
864
824
|
|
|
865
|
-
|
|
825
|
+
```ts
|
|
826
|
+
await core.delete([{ space: "asset-space", externalId: "pump-1" }]);
|
|
827
|
+
```
|
|
866
828
|
|
|
867
|
-
|
|
829
|
+
All Cognite Core view types are exported from `industrial-model` and can be imported directly for use with `IndustrialModelClient` if needed:
|
|
868
830
|
|
|
869
831
|
```ts
|
|
870
|
-
|
|
871
|
-
validateResults: true,
|
|
872
|
-
});
|
|
832
|
+
import type { CogniteAsset, CogniteEquipment, CogniteTimeSeries } from "industrial-model";
|
|
873
833
|
```
|
|
874
834
|
|
|
875
|
-
|
|
835
|
+
### Inward List-Relation Limitation
|
|
876
836
|
|
|
877
|
-
|
|
837
|
+
Cognite rejects server-side inward traversal of list direct relations. As a result, `timeSeries`, `files`, and `activities` cannot be expanded from `CogniteAsset`. Attempting to select them throws a descriptive error before the Cognite API is called, naming the view to query and the field to filter on.
|
|
878
838
|
|
|
879
|
-
|
|
880
|
-
|--------|------|-------------|
|
|
881
|
-
| `viewExternalId` | `string` | The view to query |
|
|
882
|
-
| `select` | `QuerySelect<TModel>` | Optional. Defaults to `{ _all: true }` (all scalar fields). Use `_all: true` explicitly or list fields; use nested objects for relations |
|
|
883
|
-
| `filters` | `WhereInput<TModel>` | Filter conditions (supports nested relation filters) |
|
|
884
|
-
| `sort` | `SortInput<TModel>` | Sort by primitive fields on the **root** view only |
|
|
885
|
-
| `limit` | `number` | Root page size (default `1000`). Use `-1` to fetch all root pages automatically |
|
|
886
|
-
| `cursor` | `string \| null` | Pagination cursor from a previous response |
|
|
839
|
+
The alternative is to query the target view directly and filter by the relation field pointing back to the asset:
|
|
887
840
|
|
|
888
|
-
|
|
841
|
+
```ts
|
|
842
|
+
// not supported — throws before calling Cognite
|
|
843
|
+
await core.query("CogniteAsset")({
|
|
844
|
+
select: { timeSeries: { name: true } } as never,
|
|
845
|
+
});
|
|
846
|
+
|
|
847
|
+
// correct alternative: query CogniteTimeSeries and filter by assets
|
|
848
|
+
const { items } = await core.query("CogniteTimeSeries")({
|
|
849
|
+
select: { name: true, type: true },
|
|
850
|
+
filters: {
|
|
851
|
+
assets: { containsAny: [{ space: "my-space", externalId: "WMT:VAL" }] },
|
|
852
|
+
},
|
|
853
|
+
});
|
|
854
|
+
```
|
|
889
855
|
|
|
890
|
-
|
|
856
|
+
## Custom Data Models
|
|
891
857
|
|
|
892
|
-
|
|
858
|
+
The client can query any FDM in your CDF project. Cognite Core is not required.
|
|
893
859
|
|
|
894
860
|
```ts
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
861
|
+
const model = new IndustrialModelClient(client, {
|
|
862
|
+
space: "my-custom-space",
|
|
863
|
+
externalId: "MyPlantModel",
|
|
864
|
+
version: "1",
|
|
865
|
+
});
|
|
866
|
+
|
|
867
|
+
type PlantArea = IndustrialModel<{
|
|
868
|
+
name: string;
|
|
869
|
+
code: string;
|
|
870
|
+
site?: NodeId;
|
|
871
|
+
}>;
|
|
872
|
+
|
|
873
|
+
const { items } = await model.query<PlantArea>()({
|
|
874
|
+
viewExternalId: "PlantArea",
|
|
875
|
+
select: {
|
|
876
|
+
name: true,
|
|
877
|
+
code: true,
|
|
878
|
+
site: true,
|
|
879
|
+
},
|
|
880
|
+
filters: {
|
|
881
|
+
code: { prefix: "AREA-" },
|
|
882
|
+
},
|
|
883
|
+
limit: 200,
|
|
884
|
+
});
|
|
899
885
|
```
|
|
900
886
|
|
|
901
|
-
|
|
887
|
+
## Complete Example
|
|
902
888
|
|
|
903
|
-
|
|
889
|
+
This example combines typed relations, nested selections, nested filters, sorting, and cursor pagination.
|
|
904
890
|
|
|
905
891
|
```ts
|
|
906
|
-
|
|
892
|
+
type AssetWithRelations = IndustrialModel<
|
|
893
|
+
ModelProps<CogniteAsset>,
|
|
894
|
+
ModelRelations<CogniteAsset> & {
|
|
895
|
+
children?: CogniteAsset[];
|
|
896
|
+
}
|
|
897
|
+
>;
|
|
898
|
+
|
|
899
|
+
const { items, cursor } = await model.query<AssetWithRelations>()({
|
|
907
900
|
viewExternalId: "CogniteAsset",
|
|
908
901
|
select: {
|
|
902
|
+
name: true,
|
|
903
|
+
description: true,
|
|
904
|
+
tags: true,
|
|
909
905
|
parent: {
|
|
910
906
|
name: true,
|
|
907
|
+
assetClass: {
|
|
908
|
+
name: true,
|
|
909
|
+
code: true,
|
|
910
|
+
},
|
|
911
|
+
},
|
|
912
|
+
children: {
|
|
913
|
+
name: true,
|
|
914
|
+
},
|
|
915
|
+
},
|
|
916
|
+
filters: {
|
|
917
|
+
name: { prefix: "WMT" },
|
|
918
|
+
parent: {
|
|
919
|
+
name: { exists: true },
|
|
911
920
|
},
|
|
921
|
+
OR: [
|
|
922
|
+
{ tags: { containsAny: ["critical"] } },
|
|
923
|
+
{ sourceId: { eq: "sap" } },
|
|
924
|
+
],
|
|
925
|
+
},
|
|
926
|
+
sort: {
|
|
927
|
+
name: "ascending",
|
|
912
928
|
},
|
|
929
|
+
limit: 25,
|
|
930
|
+
cursor: null,
|
|
913
931
|
});
|
|
914
932
|
|
|
915
|
-
|
|
916
|
-
|
|
933
|
+
if (cursor) {
|
|
934
|
+
const next = await model.query<AssetWithRelations>()({
|
|
935
|
+
viewExternalId: "CogniteAsset",
|
|
936
|
+
select: {
|
|
937
|
+
name: true,
|
|
938
|
+
description: true,
|
|
939
|
+
tags: true,
|
|
940
|
+
parent: {
|
|
941
|
+
name: true,
|
|
942
|
+
assetClass: {
|
|
943
|
+
name: true,
|
|
944
|
+
code: true,
|
|
945
|
+
},
|
|
946
|
+
},
|
|
947
|
+
},
|
|
948
|
+
filters: {
|
|
949
|
+
name: { prefix: "WMT" },
|
|
950
|
+
parent: {
|
|
951
|
+
name: { exists: true },
|
|
952
|
+
},
|
|
953
|
+
},
|
|
954
|
+
sort: {
|
|
955
|
+
name: "ascending",
|
|
956
|
+
},
|
|
957
|
+
limit: 25,
|
|
958
|
+
cursor,
|
|
959
|
+
});
|
|
960
|
+
}
|
|
917
961
|
```
|
|
918
962
|
|
|
919
|
-
|
|
963
|
+
## API Reference
|
|
920
964
|
|
|
921
|
-
|
|
922
|
-
|--------|------|-------------|
|
|
923
|
-
| `viewExternalId` | `string` | The view to aggregate |
|
|
924
|
-
| `groupBy` | `AggregateGroupBy<TModel>` | Optional. Object of groupable properties set to `true` (max 5) |
|
|
925
|
-
| `filters` | `WhereInput<TModel>` | Same filter syntax as `query` |
|
|
926
|
-
| `aggregate` | `AggregateDefinition<TModel>` | Optional. One of `avg`, `min`, `max`, `sum`, or `count` per call |
|
|
965
|
+
### `new CogniteCoreClient(client, options?)`
|
|
927
966
|
|
|
928
|
-
|
|
967
|
+
| Parameter | Type | Description |
|
|
968
|
+
| --- | --- | --- |
|
|
969
|
+
| `client` | `CogniteClient` | Authenticated Cognite SDK client. |
|
|
970
|
+
| `options` | `IndustrialModelClientOptions` | Optional. Same options as `IndustrialModelClient`. |
|
|
971
|
+
|
|
972
|
+
Pre-configured for the Cognite Core Data Model (`cdf_cdm/CogniteCore/v1`). The exported constant `COGNITE_CORE_DATA_MODEL` holds the data model identifier if you need to pass it to other utilities.
|
|
973
|
+
|
|
974
|
+
### `core.query(viewExternalId)(options)`
|
|
975
|
+
|
|
976
|
+
Same as `model.query<TModel>()(options)` on `IndustrialModelClient`, except the view is provided as the first positional argument and the model type is inferred from it. The `viewExternalId` option is not accepted in the second call. `viewExternalId` must be a valid `CogniteCoreViewExternalId`.
|
|
977
|
+
|
|
978
|
+
### `core.aggregate(viewExternalId)(options)`
|
|
979
|
+
|
|
980
|
+
Same as `model.aggregate<TModel>()(options)` on `IndustrialModelClient`, with the view name as the first positional argument.
|
|
929
981
|
|
|
930
|
-
`
|
|
982
|
+
### `core.upsert(viewExternalId)(options)`
|
|
983
|
+
|
|
984
|
+
Same as `model.upsert<TModel>()(options)` on `IndustrialModelClient`, with the view name as the first positional argument. The model type is inferred from the Cognite Core view name.
|
|
985
|
+
|
|
986
|
+
### `core.delete(items)`
|
|
987
|
+
|
|
988
|
+
Same as `model.delete(items)` on `IndustrialModelClient`. Deletes nodes by `space` and `externalId`; no view name is required.
|
|
989
|
+
|
|
990
|
+
### `new IndustrialModelClient(client, dataModelId, options?)`
|
|
991
|
+
|
|
992
|
+
| Parameter | Type | Description |
|
|
993
|
+
| --- | --- | --- |
|
|
994
|
+
| `client` | `CogniteClient` | Authenticated Cognite SDK client. |
|
|
995
|
+
| `dataModelId` | `DataModelId` | Data model `space`, `externalId`, and `version`. |
|
|
996
|
+
| `options.validateResults` | `boolean` | Optional. Parse result items with generated Zod schemas. |
|
|
997
|
+
|
|
998
|
+
On the first query or aggregation, view definitions are loaded from CDF and cached for the lifetime of the client instance.
|
|
999
|
+
|
|
1000
|
+
### `model.query<TModel>()(options)`
|
|
1001
|
+
|
|
1002
|
+
`query()` uses a curried form so you can provide the model type first and still get return-type inference from `select`.
|
|
1003
|
+
|
|
1004
|
+
| Option | Description |
|
|
1005
|
+
| --- | --- |
|
|
1006
|
+
| `viewExternalId` | View to query. |
|
|
1007
|
+
| `select` | Optional. Defaults to `{ _all: true }`. Use nested objects for relations. |
|
|
1008
|
+
| `filters` | Field, logical, search, and nested relation filters. |
|
|
1009
|
+
| `sort` | Sort by primitive fields on the root view only. |
|
|
1010
|
+
| `limit` | Root page size. Defaults to `1000`. Use `-1` to fetch all root pages. |
|
|
1011
|
+
| `cursor` | Root pagination cursor from a previous response. |
|
|
1012
|
+
|
|
1013
|
+
Returns:
|
|
931
1014
|
|
|
932
1015
|
```ts
|
|
933
|
-
type
|
|
934
|
-
|
|
935
|
-
|
|
1016
|
+
type QueryResult<TItem> = {
|
|
1017
|
+
items: TItem[];
|
|
1018
|
+
cursor: string | null;
|
|
936
1019
|
};
|
|
937
1020
|
```
|
|
938
1021
|
|
|
939
|
-
|
|
1022
|
+
Each item includes instance metadata such as `space`, `externalId`, `version`, `createdTime`, `deletedTime`, and `lastUpdatedTime`, plus the selected fields.
|
|
940
1023
|
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
| `count` | `{ count: "name" }` | Count non-null values for a property |
|
|
945
|
-
| `avg` | `{ avg: "volume" }` | Average of a numeric property |
|
|
946
|
-
| `min` | `{ min: "volume" }` | Minimum numeric value |
|
|
947
|
-
| `max` | `{ max: "volume" }` | Maximum numeric value |
|
|
948
|
-
| `sum` | `{ sum: "volume" }` | Sum of a numeric property |
|
|
1024
|
+
### `model.upsert<TModel>()(options)`
|
|
1025
|
+
|
|
1026
|
+
`upsert()` uses the same model type as `query()` and accepts partial node patches. It returns the Cognite apply result items.
|
|
949
1027
|
|
|
950
|
-
|
|
1028
|
+
| Option | Description |
|
|
1029
|
+
| --- | --- |
|
|
1030
|
+
| `viewExternalId` | View to create or patch. |
|
|
1031
|
+
| `items` | Node patches. Each item must include `space` and `externalId`. Inputs larger than Cognite's 1000-item apply limit are split into multiple calls. |
|
|
1032
|
+
| `replace` | Optional. Enables Cognite apply replace semantics for submitted container-backed properties. |
|
|
1033
|
+
| `edgeMode` | Optional. `"append"` by default; use `"replace"` to remove existing edge connection edges for submitted edge fields before applying the new references. |
|
|
1034
|
+
| `onEdgeCreation` | Optional map of edge connection property names to callbacks that generate edge IDs. Required for every edge connection property that creates one or more edges. |
|
|
951
1035
|
|
|
952
|
-
|
|
1036
|
+
Returns:
|
|
953
1037
|
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
1038
|
+
```ts
|
|
1039
|
+
type UpsertResult = {
|
|
1040
|
+
items: Array<{
|
|
1041
|
+
instanceType: "node" | "edge";
|
|
1042
|
+
space: string;
|
|
1043
|
+
externalId: string;
|
|
1044
|
+
version?: number;
|
|
1045
|
+
wasModified?: boolean;
|
|
1046
|
+
createdTime?: number;
|
|
1047
|
+
lastUpdatedTime?: number;
|
|
1048
|
+
}>;
|
|
1049
|
+
};
|
|
1050
|
+
```
|
|
1051
|
+
|
|
1052
|
+
### `model.delete<TItem extends NodeId>(items)`
|
|
1053
|
+
|
|
1054
|
+
Deletes nodes by identity. Each item must include `space` and `externalId`; extra fields are ignored. Inputs larger than Cognite's 1000-item apply limit are split into multiple calls.
|
|
1055
|
+
|
|
1056
|
+
```ts
|
|
1057
|
+
await model.delete([{ space: "asset-space", externalId: "pump-1" }]);
|
|
1058
|
+
```
|
|
1059
|
+
|
|
1060
|
+
Returns:
|
|
957
1061
|
|
|
958
|
-
|
|
1062
|
+
```ts
|
|
1063
|
+
type DeleteResult = {
|
|
1064
|
+
items: Array<{
|
|
1065
|
+
instanceType: "node";
|
|
1066
|
+
space: string;
|
|
1067
|
+
externalId: string;
|
|
1068
|
+
version?: number;
|
|
1069
|
+
wasModified?: boolean;
|
|
1070
|
+
createdTime?: number;
|
|
1071
|
+
lastUpdatedTime?: number;
|
|
1072
|
+
}>;
|
|
1073
|
+
};
|
|
1074
|
+
```
|
|
959
1075
|
|
|
960
|
-
|
|
961
|
-
|
|
1076
|
+
### `model.aggregate<TModel>()(options)`
|
|
1077
|
+
|
|
1078
|
+
| Option | Description |
|
|
1079
|
+
| --- | --- |
|
|
1080
|
+
| `viewExternalId` | View to aggregate. |
|
|
1081
|
+
| `groupBy` | Groupable properties set to `true`; max 5 fields. |
|
|
1082
|
+
| `filters` | Same filter syntax as `query()`. |
|
|
1083
|
+
| `aggregate` | One of `avg`, `min`, `max`, `sum`, or `count`. |
|
|
1084
|
+
|
|
1085
|
+
Provide at least one of `groupBy` or `aggregate`. Omit `aggregate` to fetch distinct grouped values. The client requests up to 1000 aggregate rows.
|
|
1086
|
+
|
|
1087
|
+
| Aggregate | Input | Use case |
|
|
1088
|
+
| --- | --- | --- |
|
|
1089
|
+
| `count` | `{ count: {} }` | Row count, optionally filtered. |
|
|
1090
|
+
| `count` | `{ count: "name" }` | Count non-null values for a property. |
|
|
1091
|
+
| `avg` | `{ avg: "volume" }` | Average of a numeric property. |
|
|
1092
|
+
| `min` | `{ min: "volume" }` | Minimum numeric value. |
|
|
1093
|
+
| `max` | `{ max: "volume" }` | Maximum numeric value. |
|
|
1094
|
+
| `sum` | `{ sum: "volume" }` | Sum of a numeric property. |
|
|
1095
|
+
|
|
1096
|
+
### Filter Operators
|
|
1097
|
+
|
|
1098
|
+
| Field type | Operators |
|
|
1099
|
+
| --- | --- |
|
|
962
1100
|
| `string` | `eq`, `in`, `prefix`, `search`, `exists` |
|
|
963
1101
|
| `number` | `eq`, `in`, `gt`, `gte`, `lt`, `lte`, `exists` |
|
|
964
1102
|
| `boolean` | `eq`, `exists` |
|
|
965
|
-
| timestamp / `Date` | `eq`, `in`, `gt`, `gte`, `lt`, `lte`, `exists`
|
|
1103
|
+
| timestamp / `Date` | `eq`, `in`, `gt`, `gte`, `lt`, `lte`, `exists` |
|
|
966
1104
|
| `NodeId` | `eq`, `in`, `exists` |
|
|
967
1105
|
| `string[]` | `containsAny`, `containsAll`, `search`, `exists` |
|
|
968
1106
|
| `T[]` | `containsAny`, `containsAll`, `exists` |
|
|
969
1107
|
|
|
970
|
-
Logical combinators `AND`, `OR`, and `NOT` are supported at any nesting level, including
|
|
1108
|
+
Logical combinators `AND`, `OR`, and `NOT` are supported at any nesting level, including nested relation filters.
|
|
971
1109
|
|
|
972
|
-
|
|
1110
|
+
### Relation Traversal
|
|
973
1111
|
|
|
974
|
-
|
|
1112
|
+
| Relation type | Description |
|
|
1113
|
+
| --- | --- |
|
|
1114
|
+
| Direct relations | Outward node references such as `parent`, `asset`, and `unit`. |
|
|
1115
|
+
| Reverse relations | Relations declared only in `TRelations`, such as `children` on `CogniteAsset`. |
|
|
1116
|
+
| Edge relations | Edge-backed relations declared in `TRelations`, such as `images360` on `Cognite3DObject`. |
|
|
1117
|
+
| Depth | Nested `select` and `filters` are supported up to 3 levels deep. |
|
|
975
1118
|
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
1119
|
+
### Exports
|
|
1120
|
+
|
|
1121
|
+
**Core**
|
|
1122
|
+
|
|
1123
|
+
| Symbol | Description |
|
|
1124
|
+
| --- | --- |
|
|
1125
|
+
| `IndustrialModelClient` | Main client for any FDM data model. |
|
|
1126
|
+
| `IndustrialModel`, `ModelProps`, `ModelRelations` | Type helpers for model properties and relation metadata. |
|
|
1127
|
+
| `NodeId`, `DataModelId` | Instance and data model identifiers. |
|
|
1128
|
+
| `QuerySelect` | Type helper for reusable query selections. |
|
|
1129
|
+
| `QueryResult`, `QueryResultItem` | Query output types. |
|
|
1130
|
+
| `AggregateResult`, `AggregateResultItem` | Aggregate output types. |
|
|
1131
|
+
| `UpsertOptions`, `UpsertNode`, `UpsertProperties` | Upsert input helper types. |
|
|
1132
|
+
| `UpsertResult`, `UpsertResultItem` | Upsert output types. |
|
|
1133
|
+
| `DeleteExecutor`, `DeleteResult`, `DeleteResultItem` | Delete helper and output types. |
|
|
1134
|
+
| `EdgeCreationContext`, `EdgeCreationCallback`, `EdgeCreationCallbacks`, `EdgeMode` | Edge upsert helper types. |
|
|
1135
|
+
| `IndustrialModelClientOptions` | Client configuration options. |
|
|
1136
|
+
|
|
1137
|
+
**Cognite Core**
|
|
1138
|
+
|
|
1139
|
+
| Symbol | Description |
|
|
1140
|
+
| --- | --- |
|
|
1141
|
+
| `CogniteCoreClient` | Convenience client pre-configured for `cdf_cdm/CogniteCore/v1`. |
|
|
1142
|
+
| `COGNITE_CORE_DATA_MODEL` | Data model identifier constant for Cognite Core v1. |
|
|
1143
|
+
| `CogniteCoreViewExternalId` | Union type of all Cognite Core view names. |
|
|
1144
|
+
| `CogniteAsset`, `CogniteAssetClass`, `CogniteAssetType` | Asset hierarchy views. |
|
|
1145
|
+
| `CogniteEquipment`, `CogniteEquipmentType` | Equipment views. |
|
|
1146
|
+
| `CogniteFile`, `CogniteFileCategory` | File views. |
|
|
1147
|
+
| `CogniteActivity` | Activity view. |
|
|
1148
|
+
| `CogniteTimeSeries` | Time series view. |
|
|
1149
|
+
| `CogniteUnit` | Unit of measurement view. |
|
|
1150
|
+
| `CogniteAnnotation`, `CogniteDiagramAnnotation` | Annotation views. |
|
|
1151
|
+
| `CogniteSourceSystem` | Source system view. |
|
|
1152
|
+
| `CogniteDescribable`, `CogniteSourceable`, `CogniteSchedulable`, `CogniteVisualizable` | Mixin views. |
|
|
1153
|
+
| `Cognite3DObject`, `Cognite3DModel`, `Cognite3DRevision`, `Cognite3DTransformation` | 3D object and model views. |
|
|
1154
|
+
| `CogniteCADModel`, `CogniteCADRevision`, `CogniteCADNode` | CAD-specific views. |
|
|
1155
|
+
| `CognitePointCloudModel`, `CognitePointCloudRevision`, `CognitePointCloudVolume` | Point cloud views. |
|
|
1156
|
+
| `Cognite360Image`, `Cognite360ImageModel`, `Cognite360ImageCollection`, `Cognite360ImageStation`, `Cognite360ImageAnnotation` | 360 image views. |
|
|
1157
|
+
| `CogniteCubeMap` | Cube map view. |
|
|
980
1158
|
|
|
981
1159
|
## Releasing
|
|
982
1160
|
|