cognite-create 0.2.15 → 0.2.16

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.
@@ -0,0 +1,2023 @@
1
+ ---
2
+ alwaysApply: true
3
+ ---
4
+
5
+ # Cognite Data Modeling SDK Guide
6
+
7
+ ## Introduction
8
+
9
+ The Cognite Data Modeling service (DMS) enables you to build, populate, and query flexible data models in Cognite Data Fusion (CDF). This SDK provides JavaScript/TypeScript APIs to work with the core components of data modeling: **Instances** (nodes and edges), **Views**, **Containers**, and **Data Models**. Together, these components allow you to create an industrial knowledge graph that represents your assets, their relationships, and associated data in a structured, scalable way.
10
+
11
+ Data modeling in CDF follows a property graph approach where:
12
+
13
+ - **Nodes** represent entities (like assets, equipment, or documents)
14
+ - **Edges** represent relationships between nodes
15
+ - **Properties** store the actual data values
16
+ - **Views** define the schema and how data is accessed
17
+ - **Containers** handle the physical storage and indexing
18
+ - **Data Models** group views together for specific use cases
19
+
20
+ ## Installation
21
+
22
+ To use the data modeling APIs, install the Cognite SDK:
23
+
24
+ Using npm:
25
+
26
+ ```bash
27
+ npm install @cognite/sdk --save
28
+ ```
29
+
30
+ Using yarn:
31
+
32
+ ```bash
33
+ yarn add @cognite/sdk
34
+ ```
35
+
36
+ ## Initialization
37
+
38
+ Initialize the CogniteClient with your project details and authentication:
39
+
40
+ ```javascript
41
+ import { CogniteClient } from "@cognite/sdk";
42
+
43
+ const client = new CogniteClient({
44
+ appId: "YOUR_APP_NAME",
45
+ project: "YOUR_PROJECT_NAME",
46
+ oidcTokenProvider: async () => {
47
+ return "YOUR_OIDC_ACCESS_TOKEN";
48
+ },
49
+ baseUrl: "https://api.cognitedata.com", // Optional
50
+ });
51
+ ```
52
+
53
+ ## Core Concepts
54
+
55
+ ### Spaces
56
+
57
+ Spaces are logical groupings that help organize and secure data model components. Each container, view, data model, and instance belongs to a specific space. Spaces provide:
58
+
59
+ - **Organization**: Group related data model components together
60
+ - **Access Control**: Manage permissions at the space level
61
+ - **Isolation**: Separate different projects or domains
62
+ - **Namespacing**: Avoid naming conflicts between components
63
+
64
+ CDF provides several system spaces:
65
+
66
+ - `cdf_cdm`: Contains the Cognite core data model
67
+ - `cdf_cdm_units`: Contains unit definitions
68
+ - `cdf_extraction_extensions`: Used by Cognite extractors
69
+
70
+ Reserved space names that cannot be used:
71
+
72
+ - `space`, `cdf`, `dms`, `pg3`, `shared`, `system`, `node`, `edge`
73
+
74
+ ### Property Graph Model
75
+
76
+ CDF uses a property graph where:
77
+
78
+ - **Nodes** are vertices in the graph with properties
79
+ - **Edges** are directed connections between nodes with their own properties
80
+ - **Direct Relations** are properties that reference other nodes (stored on the node itself)
81
+ - **Types** categorize nodes and edges using direct relations
82
+
83
+ ### Schema Components Hierarchy
84
+
85
+ 1. **Containers**: Define physical storage with properties, constraints, and indexes
86
+ 2. **Views**: Provide semantic layers over containers, supporting inheritance and filtering
87
+ 3. **Data Models**: Group related views for specific use cases or applications
88
+
89
+ ## Key Methods & Functions
90
+
91
+ ### Spaces API
92
+
93
+ The Spaces API manages the logical groupings that organize and secure your data model components.
94
+
95
+ #### client.spaces.upsert(params)
96
+
97
+ - **Description**: Creates or updates spaces
98
+ - **Parameters**:
99
+ - `params` (SpaceCreateDefinition[], required): Array of space definitions
100
+ - **Return Type**: Promise<SpaceCollectionResponseV3Response>
101
+ - **Example**:
102
+
103
+ ```javascript
104
+ const spaces = await client.spaces.upsert([
105
+ {
106
+ space: "equipment_data",
107
+ name: "Equipment Data",
108
+ description: "Space for equipment-related data models and instances",
109
+ },
110
+ {
111
+ space: "maintenance_ops",
112
+ name: "Maintenance Operations",
113
+ description: "Space for maintenance workflows and history",
114
+ },
115
+ ]);
116
+
117
+ console.log(`Created ${spaces.items.length} spaces`);
118
+ ```
119
+
120
+ #### client.spaces.list(params?)
121
+
122
+ - **Description**: Lists spaces with optional filtering
123
+ - **Parameters**:
124
+ - `params` (Object, optional): Query parameters
125
+ - `includeGlobal` (boolean): Include global/system spaces
126
+ - `limit` (number): Maximum number of results
127
+ - `cursor` (string): Pagination cursor
128
+ - **Return Type**: CursorAndAsyncIterator<SpaceDefinition>
129
+ - **Example**:
130
+
131
+ ```javascript
132
+ // List user-created spaces
133
+ const userSpaces = await client.spaces
134
+ .list({
135
+ includeGlobal: false,
136
+ limit: 100,
137
+ })
138
+ .autoPagingToArray();
139
+
140
+ console.log("User spaces:");
141
+ userSpaces.forEach((space) => {
142
+ console.log(`- ${space.space}: ${space.name}`);
143
+ });
144
+
145
+ // List all spaces including global ones
146
+ const allSpaces = await client.spaces
147
+ .list({
148
+ includeGlobal: true,
149
+ })
150
+ .autoPagingToArray();
151
+
152
+ console.log(`Total spaces: ${allSpaces.length}`);
153
+ ```
154
+
155
+ #### client.spaces.retrieve(params)
156
+
157
+ - **Description**: Retrieves specific spaces by ID
158
+ - **Parameters**:
159
+ - `params` (string[], required): Array of space IDs
160
+ - **Return Type**: Promise<SpaceCollectionResponseV3Response>
161
+ - **Example**:
162
+
163
+ ```javascript
164
+ const spaces = await client.spaces.retrieve([
165
+ "equipment_data",
166
+ "maintenance_ops",
167
+ "cdf_cdm", // Core data model space
168
+ ]);
169
+
170
+ spaces.items.forEach((space) => {
171
+ console.log(`Space: ${space.space}`);
172
+ console.log(` Name: ${space.name}`);
173
+ console.log(` Description: ${space.description}`);
174
+ console.log(` Is Global: ${space.isGlobal}`);
175
+ console.log(` Created: ${new Date(space.createdTime)}`);
176
+ });
177
+ ```
178
+
179
+ #### client.spaces.delete(params)
180
+
181
+ - **Description**: Deletes spaces (and all contained data)
182
+ - **Parameters**:
183
+ - `params` (string[], required): Array of space IDs to delete
184
+ - **Return Type**: Promise<{ items: string[] }>
185
+ - **Example**:
186
+
187
+ ```javascript
188
+ // WARNING: This deletes the space and ALL its contents
189
+ const result = await client.spaces.delete(["obsolete_space"]);
190
+
191
+ console.log(`Deleted spaces: ${result.items.join(", ")}`);
192
+ ```
193
+
194
+ **Important**: Deleting a space will delete all containers, views, data models, and instances within that space. This operation cannot be undone.
195
+
196
+ ### Instances API
197
+
198
+ The Instances API manages nodes and edges in your property graph.
199
+
200
+ #### client.instances.upsert(params)
201
+
202
+ - **Description**: Creates or updates nodes and edges
203
+ - **Parameters**:
204
+ - `params` (NodeAndEdgeCreateCollection, required): Collection of nodes/edges to upsert
205
+ - **Return Type**: Promise<SlimNodeAndEdgeCollectionResponse>
206
+ - **Example**:
207
+
208
+ ```javascript
209
+ const result = await client.instances.upsert({
210
+ items: [
211
+ {
212
+ instanceType: "node",
213
+ externalId: "pump-001",
214
+ space: "industrial-assets",
215
+ sources: [
216
+ {
217
+ source: {
218
+ externalId: "Equipment",
219
+ space: "cdf_core",
220
+ type: "view",
221
+ version: "v1",
222
+ },
223
+ properties: {
224
+ name: "Water Pump 001",
225
+ description: "Primary cooling system pump",
226
+ manufacturer: "ACME Corp",
227
+ serialNumber: "WP-5000-001",
228
+ },
229
+ },
230
+ ],
231
+ },
232
+ {
233
+ instanceType: "edge",
234
+ externalId: "located-in-001",
235
+ space: "industrial-assets",
236
+ type: { externalId: "locatedIn", space: "relationships" },
237
+ startNode: { externalId: "pump-001", space: "industrial-assets" },
238
+ endNode: { externalId: "facility-001", space: "industrial-assets" },
239
+ sources: [
240
+ {
241
+ source: {
242
+ externalId: "LocationRelation",
243
+ space: "relationships",
244
+ type: "view",
245
+ version: "v1",
246
+ },
247
+ properties: {
248
+ since: "2024-01-15",
249
+ floor: 2,
250
+ room: "2B",
251
+ },
252
+ },
253
+ ],
254
+ },
255
+ ],
256
+ autoCreateDirectRelations: true, // Auto-create missing target nodes
257
+ replace: false, // Merge properties instead of replacing
258
+ });
259
+ ```
260
+
261
+ #### client.instances.list(params)
262
+
263
+ - **Description**: Lists instances with filtering and pagination
264
+ - **Parameters**:
265
+ - `params` (NodeOrEdgeListRequestV3, required): Query parameters
266
+ - **Return Type**: Promise<NodeAndEdgeCollectionResponseWithCursorV3Response>
267
+ - **Example**:
268
+
269
+ ```javascript
270
+ const nodes = await client.instances.list({
271
+ instanceType: "node",
272
+ sources: [
273
+ {
274
+ source: {
275
+ externalId: "Equipment",
276
+ space: "cdf_core",
277
+ type: "view",
278
+ version: "v1",
279
+ },
280
+ },
281
+ ],
282
+ filter: {
283
+ equals: {
284
+ property: ["node", "space"],
285
+ value: "industrial-assets",
286
+ },
287
+ },
288
+ sort: [
289
+ {
290
+ property: ["name"],
291
+ direction: "ascending",
292
+ nullsFirst: false,
293
+ },
294
+ ],
295
+ limit: 100,
296
+ });
297
+
298
+ // Iterate through results
299
+ console.log(`Found ${nodes.items.length} equipment nodes`);
300
+ for (const node of nodes.items) {
301
+ console.log(node.externalId, node.properties);
302
+ }
303
+ ```
304
+
305
+ #### client.instances.retrieve(params)
306
+
307
+ - **Description**: Retrieves specific instances by ID
308
+ - **Parameters**:
309
+ - `params` (ListOfSpaceExternalIdsRequestWithTyping, required): Items to retrieve
310
+ - **Return Type**: Promise<NodeAndEdgeCollectionResponseV3Response>
311
+ - **Example**:
312
+
313
+ ```javascript
314
+ const instances = await client.instances.retrieve({
315
+ sources: [
316
+ {
317
+ source: {
318
+ externalId: "Equipment",
319
+ space: "cdf_core",
320
+ type: "view",
321
+ version: "v1",
322
+ },
323
+ },
324
+ ],
325
+ items: [
326
+ {
327
+ externalId: "pump-001",
328
+ space: "industrial-assets",
329
+ instanceType: "node",
330
+ },
331
+ {
332
+ externalId: "pump-002",
333
+ space: "industrial-assets",
334
+ instanceType: "node",
335
+ },
336
+ ],
337
+ });
338
+ ```
339
+
340
+ #### client.instances.search(params)
341
+
342
+ - **Description**: Searches instances using text queries and filters
343
+ - **Parameters**:
344
+ - `params` (NodeOrEdgeSearchRequest, required): Search parameters
345
+ - **Return Type**: Promise<NodeAndEdgeCollectionResponseV3Response>
346
+ - **Example**:
347
+
348
+ ```javascript
349
+ const searchResults = await client.instances.search({
350
+ view: {
351
+ externalId: "Equipment",
352
+ space: "cdf_core",
353
+ type: "view",
354
+ version: "v1",
355
+ },
356
+ query: "pump ACME", // Text search
357
+ filter: {
358
+ and: [
359
+ {
360
+ equals: {
361
+ property: ["manufacturer"],
362
+ value: "ACME Corp",
363
+ },
364
+ },
365
+ {
366
+ range: {
367
+ property: ["installedDate"],
368
+ gte: "2023-01-01",
369
+ },
370
+ },
371
+ ],
372
+ },
373
+ limit: 50,
374
+ });
375
+ ```
376
+
377
+ #### client.instances.aggregate(params)
378
+
379
+ - **Description**: Aggregates instance data with grouping and calculations
380
+ - **Parameters**:
381
+ - `params` (ViewAggregationRequest, required): Aggregation query
382
+ - **Return Type**: Promise<AggregationResponse>
383
+ - **Example**:
384
+
385
+ ```javascript
386
+ const aggregation = await client.instances.aggregate({
387
+ view: {
388
+ externalId: "Equipment",
389
+ space: "cdf_core",
390
+ type: "view",
391
+ version: "v1",
392
+ },
393
+ groupBy: ["manufacturer", "equipmentType"],
394
+ aggregates: [
395
+ { count: { property: "externalId" } },
396
+ { avg: { property: "maintenanceCost" } },
397
+ { sum: { property: "powerRating" } },
398
+ ],
399
+ filter: {
400
+ prefix: {
401
+ property: ["name"],
402
+ value: "Pump",
403
+ },
404
+ },
405
+ limit: 10,
406
+ });
407
+
408
+ // Process results
409
+ for (const group of aggregation.items) {
410
+ console.log(
411
+ `${group.group[0]} - ${group.group[1]}: ${group.aggregates[0].value} units`
412
+ );
413
+ }
414
+ ```
415
+
416
+ #### client.instances.query(params)
417
+
418
+ - **Description**: Executes complex queries across multiple node/edge types
419
+ - **Parameters**:
420
+ - `params` (QueryRequest, required): Query definition
421
+ - **Return Type**: Promise<QueryResponse>
422
+ - **Example**:
423
+
424
+ ```javascript
425
+ const queryResult = await client.instances.query({
426
+ with: {
427
+ // Define data sources
428
+ pumps: {
429
+ nodes: {
430
+ filter: {
431
+ equals: {
432
+ property: ["node", "type"],
433
+ value: { space: "types", externalId: "Pump" },
434
+ },
435
+ },
436
+ },
437
+ },
438
+ maintenanceEvents: {
439
+ edges: {
440
+ from: "pumps",
441
+ type: { space: "relationships", externalId: "hasMaintenanceEvent" },
442
+ direction: "outwards",
443
+ },
444
+ },
445
+ },
446
+ select: {
447
+ // Define what to return
448
+ pumps: {
449
+ sources: [
450
+ {
451
+ source: {
452
+ externalId: "Equipment",
453
+ space: "cdf_core",
454
+ type: "view",
455
+ version: "v1",
456
+ },
457
+ properties: ["name", "serialNumber", "manufacturer"],
458
+ },
459
+ ],
460
+ },
461
+ maintenanceEvents: {
462
+ sources: [
463
+ {
464
+ source: {
465
+ externalId: "MaintenanceEvent",
466
+ space: "maintenance",
467
+ type: "view",
468
+ version: "v1",
469
+ },
470
+ properties: ["scheduledDate", "description", "status"],
471
+ },
472
+ ],
473
+ },
474
+ },
475
+ parameters: {
476
+ limit: 100,
477
+ },
478
+ });
479
+ ```
480
+
481
+ #### client.instances.sync(params)
482
+
483
+ - **Description**: Synchronizes data with cursor-based pagination for large datasets
484
+ - **Parameters**:
485
+ - `params` (SyncRequest, required): Sync query with cursor support
486
+ - **Return Type**: Promise<QueryResponse>
487
+ - **Example**:
488
+
489
+ ```javascript
490
+ let cursor = null;
491
+ const allData = [];
492
+
493
+ do {
494
+ const syncResult = await client.instances.sync({
495
+ with: {
496
+ equipment: {
497
+ nodes: {
498
+ filter: {
499
+ equals: {
500
+ property: ["node", "space"],
501
+ value: "industrial-assets",
502
+ },
503
+ },
504
+ },
505
+ },
506
+ },
507
+ select: {
508
+ equipment: {},
509
+ },
510
+ cursors: cursor ? { equipment: cursor } : {},
511
+ });
512
+
513
+ allData.push(...syncResult.items.equipment);
514
+ cursor = syncResult.nextCursor?.equipment;
515
+ } while (cursor);
516
+
517
+ console.log(`Synced ${allData.length} equipment nodes`);
518
+ ```
519
+
520
+ #### client.instances.delete(items)
521
+
522
+ - **Description**: Deletes instances by ID
523
+ - **Parameters**:
524
+ - `items` (Array, required): Items to delete
525
+ - **Return Type**: Promise<{}>
526
+ - **Example**:
527
+
528
+ ```javascript
529
+ await client.instances.delete([
530
+ {
531
+ instanceType: "node",
532
+ externalId: "pump-001",
533
+ space: "industrial-assets",
534
+ },
535
+ {
536
+ instanceType: "edge",
537
+ externalId: "located-in-001",
538
+ space: "industrial-assets",
539
+ },
540
+ ]);
541
+ ```
542
+
543
+ ### Views API
544
+
545
+ Views define the semantic schema for your data, supporting inheritance and property mapping.
546
+
547
+ #### client.views.upsert(params)
548
+
549
+ - **Description**: Creates or updates view definitions
550
+ - **Parameters**:
551
+ - `params` (ViewCreateDefinition[], required): Array of view definitions
552
+ - **Return Type**: Promise<ViewCollectionResponse>
553
+ - **Example**:
554
+
555
+ ```javascript
556
+ const views = await client.views.upsert([
557
+ {
558
+ externalId: "Pump",
559
+ space: "equipment-types",
560
+ name: "Pump Equipment",
561
+ description: "View for pump equipment with extended properties",
562
+ version: "v1",
563
+ implements: [
564
+ {
565
+ type: "view",
566
+ space: "cdf_core",
567
+ externalId: "Equipment",
568
+ version: "v1",
569
+ },
570
+ ],
571
+ properties: {
572
+ flowRate: {
573
+ container: {
574
+ type: "container",
575
+ space: "equipment-data",
576
+ externalId: "PumpData",
577
+ },
578
+ containerPropertyIdentifier: "flowRate",
579
+ name: "Flow Rate",
580
+ description: "Maximum flow rate in liters per minute",
581
+ },
582
+ pressure: {
583
+ container: {
584
+ type: "container",
585
+ space: "equipment-data",
586
+ externalId: "PumpData",
587
+ },
588
+ containerPropertyIdentifier: "pressure",
589
+ name: "Operating Pressure",
590
+ description: "Operating pressure in bar",
591
+ },
592
+ manufacturer: {
593
+ container: {
594
+ type: "container",
595
+ space: "equipment-data",
596
+ externalId: "EquipmentCore",
597
+ },
598
+ containerPropertyIdentifier: "manufacturer",
599
+ name: "Manufacturer",
600
+ description: "Equipment manufacturer name",
601
+ },
602
+ },
603
+ filter: {
604
+ equals: {
605
+ property: ["node", "type"],
606
+ value: { space: "types", externalId: "Pump" },
607
+ },
608
+ },
609
+ },
610
+ ]);
611
+ ```
612
+
613
+ #### client.views.list(params)
614
+
615
+ - **Description**: Lists views with optional filtering
616
+ - **Parameters**:
617
+ - `params` (Object, optional): Query parameters
618
+ - **Return Type**: CursorAndAsyncIterator<ViewDefinition>
619
+ - **Example**:
620
+
621
+ ```javascript
622
+ // List all views in a space
623
+ const views = await client.views
624
+ .list({
625
+ space: "equipment-types",
626
+ includeInheritedProperties: true,
627
+ allVersions: false,
628
+ })
629
+ .autoPagingToArray();
630
+
631
+ // List global views
632
+ const globalViews = await client.views
633
+ .list({
634
+ includeGlobal: true,
635
+ limit: 50,
636
+ })
637
+ .autoPagingToArray();
638
+ ```
639
+
640
+ #### client.views.retrieve(params, options?)
641
+
642
+ - **Description**: Retrieves specific views by ID
643
+ - **Parameters**:
644
+ - `params` (Array, required): View references
645
+ - `options` (Object, optional): Additional options
646
+ - **Return Type**: Promise<ViewCollectionResponse>
647
+ - **Example**:
648
+
649
+ ```javascript
650
+ const views = await client.views.retrieve(
651
+ [
652
+ {
653
+ space: "cdf_core",
654
+ externalId: "Equipment",
655
+ version: "v1",
656
+ },
657
+ {
658
+ space: "equipment-types",
659
+ externalId: "Pump",
660
+ // Omit version to get latest
661
+ },
662
+ ],
663
+ {
664
+ includeInheritedProperties: true,
665
+ }
666
+ );
667
+
668
+ // Inspect view properties
669
+ for (const view of views.items) {
670
+ console.log(`View: ${view.externalId}`);
671
+ console.log(`Properties:`, Object.keys(view.properties || {}));
672
+ console.log(`Implements:`, view.implements);
673
+ }
674
+ ```
675
+
676
+ #### client.views.delete(params)
677
+
678
+ - **Description**: Deletes views
679
+ - **Parameters**:
680
+ - `params` (Array, required): View references to delete
681
+ - **Return Type**: Promise<ListOfVersionReferences>
682
+ - **Example**:
683
+
684
+ ```javascript
685
+ await client.views.delete([
686
+ {
687
+ space: "equipment-types",
688
+ externalId: "ObsoletePumpView",
689
+ version: "v1",
690
+ },
691
+ ]);
692
+ ```
693
+
694
+ ### Containers API
695
+
696
+ Containers define the physical storage layer with properties, constraints, and indexes.
697
+
698
+ #### client.containers.upsert(params)
699
+
700
+ - **Description**: Creates or updates container definitions
701
+ - **Parameters**:
702
+ - `params` (ContainerCreateDefinition[], required): Container definitions
703
+ - **Return Type**: Promise<ContainerCollectionResponse>
704
+ - **Example**:
705
+
706
+ ```javascript
707
+ const containers = await client.containers.upsert([
708
+ {
709
+ space: "equipment-data",
710
+ externalId: "PumpData",
711
+ name: "Pump Data Container",
712
+ description: "Stores pump-specific properties",
713
+ usedFor: "node", // Can be 'node', 'edge', or 'all'
714
+ properties: {
715
+ flowRate: {
716
+ type: {
717
+ type: "float64",
718
+ },
719
+ nullable: true,
720
+ description: "Flow rate in liters per minute",
721
+ },
722
+ pressure: {
723
+ type: {
724
+ type: "float64",
725
+ },
726
+ nullable: false,
727
+ defaultValue: 1.0,
728
+ description: "Operating pressure in bar",
729
+ },
730
+ manufacturer: {
731
+ type: {
732
+ type: "text",
733
+ list: false,
734
+ },
735
+ nullable: true,
736
+ description: "Manufacturer name",
737
+ },
738
+ installedDate: {
739
+ type: {
740
+ type: "timestamp",
741
+ },
742
+ nullable: true,
743
+ description: "Installation date",
744
+ },
745
+ maintenanceSchedule: {
746
+ type: {
747
+ type: "json",
748
+ },
749
+ nullable: true,
750
+ description: "Maintenance schedule configuration",
751
+ },
752
+ relatedAssets: {
753
+ type: {
754
+ type: "direct",
755
+ container: {
756
+ type: "container",
757
+ space: "cdf_core",
758
+ externalId: "Asset",
759
+ },
760
+ },
761
+ list: true,
762
+ description: "Related asset references",
763
+ },
764
+ },
765
+ constraints: {
766
+ uniqueSerialNumber: {
767
+ constraintType: "unique",
768
+ properties: ["serialNumber"],
769
+ },
770
+ },
771
+ indexes: {
772
+ byManufacturer: {
773
+ properties: ["manufacturer"],
774
+ },
775
+ byInstallDate: {
776
+ properties: ["installedDate"],
777
+ },
778
+ },
779
+ },
780
+ ]);
781
+ ```
782
+
783
+ #### client.containers.list(params)
784
+
785
+ - **Description**: Lists containers
786
+ - **Parameters**:
787
+ - `params` (Object, optional): Query parameters
788
+ - **Return Type**: CursorAndAsyncIterator<ContainerDefinition>
789
+ - **Example**:
790
+
791
+ ```javascript
792
+ // List containers in a specific space
793
+ const containers = await client.containers
794
+ .list({
795
+ space: "equipment-data",
796
+ includeGlobal: false,
797
+ })
798
+ .autoPagingToArray();
799
+
800
+ // List all accessible containers including global ones
801
+ const allContainers = await client.containers
802
+ .list({
803
+ includeGlobal: true,
804
+ limit: 100,
805
+ })
806
+ .autoPagingToArray();
807
+ ```
808
+
809
+ #### client.containers.retrieve(params)
810
+
811
+ - **Description**: Retrieves specific containers
812
+ - **Parameters**:
813
+ - `params` (Array, required): Container identifiers
814
+ - **Return Type**: Promise<ContainerCollectionResponse>
815
+ - **Example**:
816
+
817
+ ```javascript
818
+ const containers = await client.containers.retrieve([
819
+ {
820
+ space: "equipment-data",
821
+ externalId: "PumpData",
822
+ },
823
+ {
824
+ space: "cdf_core",
825
+ externalId: "Asset",
826
+ },
827
+ ]);
828
+ ```
829
+
830
+ #### client.containers.delete(params)
831
+
832
+ - **Description**: Deletes containers
833
+ - **Parameters**:
834
+ - `params` (Array, required): Container identifiers
835
+ - **Return Type**: Promise<ListOfSpaceExternalIdsResponse>
836
+ - **Example**:
837
+
838
+ ```javascript
839
+ await client.containers.delete([
840
+ {
841
+ space: "equipment-data",
842
+ externalId: "ObsoleteContainer",
843
+ },
844
+ ]);
845
+ ```
846
+
847
+ ### Data Models API
848
+
849
+ Data models group related views together for specific use cases or applications.
850
+
851
+ #### client.dataModels.upsert(params)
852
+
853
+ - **Description**: Creates or updates data models
854
+ - **Parameters**:
855
+ - `params` (DataModelCreate[], required): Data model definitions
856
+ - **Return Type**: Promise<DataModelCollectionResponse>
857
+ - **Example**:
858
+
859
+ ```javascript
860
+ const dataModels = await client.dataModels.upsert([
861
+ {
862
+ space: "industrial-models",
863
+ externalId: "MaintenanceModel",
864
+ name: "Maintenance Management Model",
865
+ description: "Data model for equipment maintenance workflows",
866
+ version: "v1",
867
+ views: [
868
+ // Reference existing views
869
+ {
870
+ type: "view",
871
+ space: "cdf_core",
872
+ externalId: "Asset",
873
+ version: "v1",
874
+ },
875
+ {
876
+ type: "view",
877
+ space: "equipment-types",
878
+ externalId: "Pump",
879
+ version: "v1",
880
+ },
881
+ // Create new view inline
882
+ {
883
+ externalId: "MaintenanceEvent",
884
+ space: "maintenance",
885
+ version: "v1",
886
+ name: "Maintenance Event",
887
+ description: "Maintenance activities on equipment",
888
+ properties: {
889
+ scheduledDate: {
890
+ container: {
891
+ type: "container",
892
+ space: "maintenance",
893
+ externalId: "MaintenanceData",
894
+ },
895
+ containerPropertyIdentifier: "scheduledDate",
896
+ name: "Scheduled Date",
897
+ },
898
+ completedDate: {
899
+ container: {
900
+ type: "container",
901
+ space: "maintenance",
902
+ externalId: "MaintenanceData",
903
+ },
904
+ containerPropertyIdentifier: "completedDate",
905
+ name: "Completed Date",
906
+ },
907
+ description: {
908
+ container: {
909
+ type: "container",
910
+ space: "maintenance",
911
+ externalId: "MaintenanceData",
912
+ },
913
+ containerPropertyIdentifier: "description",
914
+ name: "Description",
915
+ },
916
+ status: {
917
+ container: {
918
+ type: "container",
919
+ space: "maintenance",
920
+ externalId: "MaintenanceData",
921
+ },
922
+ containerPropertyIdentifier: "status",
923
+ name: "Status",
924
+ },
925
+ },
926
+ },
927
+ ],
928
+ },
929
+ ]);
930
+ ```
931
+
932
+ #### client.dataModels.list(params)
933
+
934
+ - **Description**: Lists data models
935
+ - **Parameters**:
936
+ - `params` (Object, optional): Query parameters
937
+ - **Return Type**: DataModelCollectionResponseWithCursorResponse
938
+ - **Example**:
939
+
940
+ ```javascript
941
+ // List all data models
942
+ const models = await client.dataModels.list();
943
+
944
+ // List with inline views expanded
945
+ const modelsWithViews = await client.dataModels.list({
946
+ inlineViews: true,
947
+ includeGlobal: true,
948
+ allVersions: false,
949
+ });
950
+
951
+ // Iterate through models
952
+ await modelsWithViews.autoPagingEach((model) => {
953
+ console.log(`Model: ${model.externalId} v${model.version}`);
954
+ console.log(`Views: ${model.views?.length || 0}`);
955
+ });
956
+ ```
957
+
958
+ #### client.dataModels.retrieve(params, options?)
959
+
960
+ - **Description**: Retrieves specific data models
961
+ - **Parameters**:
962
+ - `params` (Array, required): Model references
963
+ - `options` (Object, optional): Additional options
964
+ - **Return Type**: Promise<DataModelCollectionResponse>
965
+ - **Example**:
966
+
967
+ ```javascript
968
+ const models = await client.dataModels.retrieve(
969
+ [
970
+ {
971
+ space: "industrial-models",
972
+ externalId: "MaintenanceModel",
973
+ version: "v1",
974
+ },
975
+ ],
976
+ {
977
+ inlineViews: true, // Include full view definitions
978
+ }
979
+ );
980
+ ```
981
+
982
+ #### client.dataModels.delete(params)
983
+
984
+ - **Description**: Deletes data models
985
+ - **Parameters**:
986
+ - `params` (Array, required): Model references
987
+ - **Return Type**: Promise<ListOfVersionReferences>
988
+ - **Example**:
989
+
990
+ ```javascript
991
+ await client.dataModels.delete([
992
+ {
993
+ space: "industrial-models",
994
+ externalId: "DeprecatedModel",
995
+ version: "v1",
996
+ },
997
+ ]);
998
+ ```
999
+
1000
+ ## Data Models
1001
+
1002
+ ### Space Structure
1003
+
1004
+ ```typescript
1005
+ interface SpaceDefinition {
1006
+ space: string; // Space ID (3-43 chars, alphanumeric with _ and -)
1007
+ name?: string; // Human-readable name
1008
+ description?: string; // Space description
1009
+ createdTime: number; // Creation timestamp (epoch milliseconds)
1010
+ lastUpdatedTime: number; // Last update timestamp
1011
+ isGlobal: boolean; // Whether this is a system/global space
1012
+ }
1013
+ ```
1014
+
1015
+ Space IDs must:
1016
+
1017
+ - Start with a letter
1018
+ - Be 3-43 characters long
1019
+ - Contain only letters, numbers, underscores, and hyphens
1020
+ - Not use reserved names: `space`, `cdf`, `dms`, `pg3`, `shared`, `system`, `node`, `edge`
1021
+
1022
+ ### Core Property Types
1023
+
1024
+ Properties in containers can have the following types:
1025
+
1026
+ ```typescript
1027
+ // Text property
1028
+ {
1029
+ type: "text",
1030
+ list?: boolean, // Array of strings
1031
+ collation?: string, // Collation for sorting
1032
+ }
1033
+
1034
+ // Primitive properties
1035
+ {
1036
+ type: "int32" | "int64" | "float32" | "float64" | "boolean",
1037
+ list?: boolean,
1038
+ }
1039
+
1040
+ // Timestamp property
1041
+ {
1042
+ type: "timestamp",
1043
+ list?: boolean,
1044
+ }
1045
+
1046
+ // JSON property
1047
+ {
1048
+ type: "json",
1049
+ list?: boolean,
1050
+ }
1051
+
1052
+ // Direct relation (reference to another node)
1053
+ {
1054
+ type: "direct",
1055
+ container?: { // Optional: enforce target node type
1056
+ type: "container",
1057
+ space: string,
1058
+ externalId: string,
1059
+ },
1060
+ list?: boolean,
1061
+ }
1062
+
1063
+ // CDF resource reference
1064
+ {
1065
+ type: "timeseries" | "file" | "sequence",
1066
+ list?: boolean,
1067
+ }
1068
+ ```
1069
+
1070
+ ### Node Structure
1071
+
1072
+ ```typescript
1073
+ interface NodeDefinition {
1074
+ instanceType: "node";
1075
+ space: string;
1076
+ externalId: string;
1077
+ version: number;
1078
+ createdTime: number;
1079
+ lastUpdatedTime: number;
1080
+ deletedTime?: number;
1081
+
1082
+ // Optional type categorization
1083
+ type?: {
1084
+ space: string;
1085
+ externalId: string;
1086
+ };
1087
+
1088
+ // Properties grouped by view/container
1089
+ properties?: {
1090
+ [viewOrContainerKey: string]: {
1091
+ [propertyName: string]: any;
1092
+ };
1093
+ };
1094
+ }
1095
+ ```
1096
+
1097
+ ### Edge Structure
1098
+
1099
+ ```typescript
1100
+ interface EdgeDefinition {
1101
+ instanceType: "edge";
1102
+ space: string;
1103
+ externalId: string;
1104
+ version: number;
1105
+ createdTime: number;
1106
+ lastUpdatedTime: number;
1107
+ deletedTime?: number;
1108
+
1109
+ // Required edge type
1110
+ type: {
1111
+ space: string;
1112
+ externalId: string;
1113
+ };
1114
+
1115
+ // Required start and end nodes
1116
+ startNode: {
1117
+ space: string;
1118
+ externalId: string;
1119
+ };
1120
+ endNode: {
1121
+ space: string;
1122
+ externalId: string;
1123
+ };
1124
+
1125
+ // Properties grouped by view/container
1126
+ properties?: {
1127
+ [viewOrContainerKey: string]: {
1128
+ [propertyName: string]: any;
1129
+ };
1130
+ };
1131
+ }
1132
+ ```
1133
+
1134
+ ### View Structure
1135
+
1136
+ ```typescript
1137
+ interface ViewDefinition {
1138
+ space: string;
1139
+ externalId: string;
1140
+ version: string;
1141
+ name?: string;
1142
+ description?: string;
1143
+ createdTime: number;
1144
+ lastUpdatedTime: number;
1145
+ writable: boolean;
1146
+ usedFor: "node" | "edge" | "all";
1147
+
1148
+ // Views this view inherits from
1149
+ implements?: Array<{
1150
+ type: "view";
1151
+ space: string;
1152
+ externalId: string;
1153
+ version: string;
1154
+ }>;
1155
+
1156
+ // Filter to apply to instances
1157
+ filter?: FilterDefinition;
1158
+
1159
+ // Property mappings
1160
+ properties?: {
1161
+ [propertyName: string]: {
1162
+ container: {
1163
+ type: "container";
1164
+ space: string;
1165
+ externalId: string;
1166
+ };
1167
+ containerPropertyIdentifier: string;
1168
+ name?: string;
1169
+ description?: string;
1170
+ // For direct relations
1171
+ source?: ViewReference;
1172
+ };
1173
+ };
1174
+ }
1175
+ ```
1176
+
1177
+ ### Container Structure
1178
+
1179
+ ```typescript
1180
+ interface ContainerDefinition {
1181
+ space: string;
1182
+ externalId: string;
1183
+ name?: string;
1184
+ description?: string;
1185
+ createdTime?: number;
1186
+ lastUpdatedTime?: number;
1187
+ usedFor?: "node" | "edge" | "all";
1188
+
1189
+ // Property definitions
1190
+ properties: {
1191
+ [propertyName: string]: {
1192
+ type: PropertyType;
1193
+ nullable?: boolean;
1194
+ autoIncrement?: boolean;
1195
+ defaultValue?: any;
1196
+ description?: string;
1197
+ name?: string;
1198
+ };
1199
+ };
1200
+
1201
+ // Constraints
1202
+ constraints?: {
1203
+ [constraintName: string]: {
1204
+ constraintType: "unique" | "required";
1205
+ properties: string[];
1206
+ };
1207
+ };
1208
+
1209
+ // Indexes for performance
1210
+ indexes?: {
1211
+ [indexName: string]: {
1212
+ properties: string[];
1213
+ };
1214
+ };
1215
+ }
1216
+ ```
1217
+
1218
+ ### Filter Definitions
1219
+
1220
+ Filters support complex queries using boolean operators and various conditions:
1221
+
1222
+ ```typescript
1223
+ // Boolean filters
1224
+ {
1225
+ and: FilterDefinition[];
1226
+ }
1227
+ {
1228
+ or: FilterDefinition[];
1229
+ }
1230
+ {
1231
+ not: FilterDefinition;
1232
+ }
1233
+
1234
+ // Comparison filters
1235
+ {
1236
+ equals: {
1237
+ property: string[];
1238
+ value: any;
1239
+ };
1240
+ }
1241
+ {
1242
+ in: {
1243
+ property: string[];
1244
+ values: any[];
1245
+ };
1246
+ }
1247
+ {
1248
+ range: {
1249
+ property: string[];
1250
+ gt?: any;
1251
+ gte?: any;
1252
+ lt?: any;
1253
+ lte?: any;
1254
+ };
1255
+ }
1256
+ {
1257
+ prefix: {
1258
+ property: string[];
1259
+ value: string;
1260
+ };
1261
+ }
1262
+ {
1263
+ exists: {
1264
+ property: string[];
1265
+ };
1266
+ }
1267
+ {
1268
+ containsAny: {
1269
+ property: string[];
1270
+ values: any[];
1271
+ };
1272
+ }
1273
+ {
1274
+ containsAll: {
1275
+ property: string[];
1276
+ values: any[];
1277
+ };
1278
+ }
1279
+
1280
+ // Nested filter for direct relations
1281
+ {
1282
+ nested: {
1283
+ scope: string[];
1284
+ filter: FilterDefinition;
1285
+ };
1286
+ }
1287
+
1288
+ // Special filters
1289
+ {
1290
+ hasData: {
1291
+ sources: Array<{
1292
+ type: "view" | "container";
1293
+ space: string;
1294
+ externalId: string;
1295
+ version?: string;
1296
+ }>;
1297
+ };
1298
+ }
1299
+ {
1300
+ matchAll: {};
1301
+ }
1302
+ ```
1303
+
1304
+ ## Core Data Model
1305
+
1306
+ CDF provides the Cognite Core Data Model (`cdf_cdm`) as a foundation for industrial data. Key concepts include:
1307
+
1308
+ ### Core Features (Reusable Property Sets)
1309
+
1310
+ - **CogniteDescribable**: Provides `name`, `description`, `tags`, and `aliases`
1311
+ - **CogniteSourceable**: Tracks data origin with `sourceId`, `sourceContext`, `source`
1312
+ - **CogniteSchedulable**: Manages time windows with `startTime`, `endTime`, `scheduledStartTime`, `scheduledEndTime`
1313
+ - **CogniteVisualizable**: Links to 3D representations via `object3D`
1314
+
1315
+ ### Core Concepts
1316
+
1317
+ - **CogniteAsset**: Represents physical or logical assets in your industrial facility
1318
+ - **CogniteEquipment**: Specialized assets representing industrial equipment
1319
+ - **CogniteTimeSeries**: References to time series data
1320
+ - **CogniteFile**: References to files stored in CDF
1321
+ - **CogniteActivity**: Represents activities or events with time boundaries
1322
+ - **CogniteAnnotation**: Comments or observations on other objects
1323
+
1324
+ ### 3D Concepts
1325
+
1326
+ - **Cognite3DModel**: 3D models (CAD, point cloud, 360 images)
1327
+ - **CogniteCADNode**: Individual nodes within CAD models
1328
+ - **CognitePointCloudVolume**: Volumes within point cloud data
1329
+ - **Cognite360Image**: 360-degree photospheres
1330
+
1331
+ ## Access Control
1332
+
1333
+ Data modeling uses capability-based access control:
1334
+
1335
+ ### Required Capabilities
1336
+
1337
+ ```javascript
1338
+ // Basic data model access
1339
+ {
1340
+ dataModelsAcl: ["READ", "WRITE"],
1341
+ dataModelInstancesAcl: ["READ", "WRITE"],
1342
+ }
1343
+
1344
+ // For using core data model
1345
+ {
1346
+ dataModelsAcl: {
1347
+ actions: ["READ"],
1348
+ scope: { spaceIdScope: { spaceIds: ["cdf_cdm"] } }
1349
+ },
1350
+ dataModelInstancesAcl: {
1351
+ actions: ["READ"],
1352
+ scope: { spaceIdScope: { spaceIds: ["cdf_cdm_units"] } }
1353
+ },
1354
+ }
1355
+
1356
+ // For specific spaces
1357
+ {
1358
+ dataModelInstancesAcl: {
1359
+ actions: ["READ", "WRITE"],
1360
+ scope: { spaceIdScope: { spaceIds: ["your-space"] } }
1361
+ },
1362
+ }
1363
+ ```
1364
+
1365
+ ## Error Handling
1366
+
1367
+ The Data Modeling APIs return specific error types:
1368
+
1369
+ ### Common Error Scenarios
1370
+
1371
+ ```javascript
1372
+ try {
1373
+ await client.instances.upsert({ items: [...] });
1374
+ } catch (error) {
1375
+ if (error instanceof CogniteError) {
1376
+ switch (error.status) {
1377
+ case 400:
1378
+ // Validation errors
1379
+ console.error("Validation failed:", error.errorMessage);
1380
+ if (error.extra?.violations) {
1381
+ // Schema violations
1382
+ console.error("Violations:", error.extra.violations);
1383
+ }
1384
+ break;
1385
+
1386
+ case 409:
1387
+ // Conflict errors (e.g., version mismatch)
1388
+ console.error("Version conflict:", error.errorMessage);
1389
+ break;
1390
+
1391
+ case 422:
1392
+ // Business logic errors
1393
+ console.error("Business rule violation:", error.errorMessage);
1394
+ break;
1395
+
1396
+ default:
1397
+ console.error(`API Error ${error.status}:`, error.errorMessage);
1398
+ }
1399
+ }
1400
+ }
1401
+ ```
1402
+
1403
+ ### Handling Large Result Sets
1404
+
1405
+ ```javascript
1406
+ // Use cursor pagination for large datasets
1407
+ async function getAllEquipment() {
1408
+ const allItems = [];
1409
+ let cursor = null;
1410
+
1411
+ do {
1412
+ try {
1413
+ const response = await client.instances.list({
1414
+ instanceType: "node",
1415
+ sources: [
1416
+ {
1417
+ source: {
1418
+ type: "view",
1419
+ space: "cdf_core",
1420
+ externalId: "Equipment",
1421
+ version: "v1",
1422
+ },
1423
+ },
1424
+ ],
1425
+ cursor: cursor,
1426
+ limit: 1000,
1427
+ });
1428
+
1429
+ allItems.push(...response.items);
1430
+ cursor = response.nextCursor;
1431
+ } catch (error) {
1432
+ console.error("Failed to fetch page:", error);
1433
+ break;
1434
+ }
1435
+ } while (cursor);
1436
+
1437
+ return allItems;
1438
+ }
1439
+ ```
1440
+
1441
+ ## Code Example
1442
+
1443
+ Here's a complete example building an industrial data model:
1444
+
1445
+ ```javascript
1446
+ import { CogniteClient } from "@cognite/sdk";
1447
+
1448
+ async function buildIndustrialDataModel() {
1449
+ // 1. Initialize client
1450
+ const client = new CogniteClient({
1451
+ appId: "IndustrialDataModeling",
1452
+ project: "my-project",
1453
+ oidcTokenProvider: async () => process.env.CDF_ACCESS_TOKEN,
1454
+ });
1455
+
1456
+ try {
1457
+ // 2. Create spaces for organization
1458
+ console.log("Creating spaces...");
1459
+ await client.spaces.upsert([
1460
+ {
1461
+ space: "equipment",
1462
+ name: "Equipment Management",
1463
+ description: "Space for equipment data models and instances",
1464
+ },
1465
+ {
1466
+ space: "maintenance",
1467
+ name: "Maintenance Operations",
1468
+ description: "Space for maintenance workflows and events",
1469
+ },
1470
+ {
1471
+ space: "types",
1472
+ name: "Type Definitions",
1473
+ description: "Space for type categorization nodes",
1474
+ },
1475
+ {
1476
+ space: "assets",
1477
+ name: "Asset Instances",
1478
+ description: "Space for actual asset instances",
1479
+ },
1480
+ {
1481
+ space: "industrial",
1482
+ name: "Industrial Models",
1483
+ description: "Space for industrial data models",
1484
+ },
1485
+ {
1486
+ space: "relationships",
1487
+ name: "Relationship Types",
1488
+ description: "Space for edge type definitions",
1489
+ },
1490
+ ]);
1491
+
1492
+ // 3. Create containers for physical storage
1493
+ console.log("Creating containers...");
1494
+ await client.containers.upsert([
1495
+ {
1496
+ space: "equipment",
1497
+ externalId: "EquipmentData",
1498
+ name: "Equipment Data",
1499
+ description: "Core equipment properties",
1500
+ usedFor: "node",
1501
+ properties: {
1502
+ serialNumber: {
1503
+ type: { type: "text" },
1504
+ nullable: false,
1505
+ description: "Unique serial number",
1506
+ },
1507
+ manufacturer: {
1508
+ type: { type: "text" },
1509
+ nullable: true,
1510
+ },
1511
+ model: {
1512
+ type: { type: "text" },
1513
+ nullable: true,
1514
+ },
1515
+ installationDate: {
1516
+ type: { type: "timestamp" },
1517
+ nullable: true,
1518
+ },
1519
+ specifications: {
1520
+ type: { type: "json" },
1521
+ nullable: true,
1522
+ description: "Technical specifications",
1523
+ },
1524
+ },
1525
+ constraints: {
1526
+ uniqueSerial: {
1527
+ constraintType: "unique",
1528
+ properties: ["serialNumber"],
1529
+ },
1530
+ },
1531
+ },
1532
+ {
1533
+ space: "equipment",
1534
+ externalId: "PumpSpecific",
1535
+ name: "Pump Specific Data",
1536
+ usedFor: "node",
1537
+ properties: {
1538
+ flowRate: {
1539
+ type: { type: "float64" },
1540
+ nullable: true,
1541
+ description: "Flow rate in L/min",
1542
+ },
1543
+ headPressure: {
1544
+ type: { type: "float64" },
1545
+ nullable: true,
1546
+ description: "Head pressure in bar",
1547
+ },
1548
+ efficiency: {
1549
+ type: { type: "float64" },
1550
+ nullable: true,
1551
+ description: "Pump efficiency percentage",
1552
+ },
1553
+ },
1554
+ },
1555
+ {
1556
+ space: "maintenance",
1557
+ externalId: "MaintenanceData",
1558
+ name: "Maintenance Data",
1559
+ usedFor: "edge",
1560
+ properties: {
1561
+ scheduledDate: {
1562
+ type: { type: "timestamp" },
1563
+ nullable: false,
1564
+ },
1565
+ completedDate: {
1566
+ type: { type: "timestamp" },
1567
+ nullable: true,
1568
+ },
1569
+ cost: {
1570
+ type: { type: "float64" },
1571
+ nullable: true,
1572
+ },
1573
+ notes: {
1574
+ type: { type: "text" },
1575
+ nullable: true,
1576
+ },
1577
+ },
1578
+ },
1579
+ ]);
1580
+
1581
+ // 4. Create views for semantic access
1582
+ console.log("Creating views...");
1583
+ await client.views.upsert([
1584
+ {
1585
+ space: "equipment",
1586
+ externalId: "BaseEquipment",
1587
+ version: "v1",
1588
+ name: "Base Equipment",
1589
+ description: "Common equipment properties",
1590
+ properties: {
1591
+ serialNumber: {
1592
+ container: {
1593
+ type: "container",
1594
+ space: "equipment",
1595
+ externalId: "EquipmentData",
1596
+ },
1597
+ containerPropertyIdentifier: "serialNumber",
1598
+ },
1599
+ manufacturer: {
1600
+ container: {
1601
+ type: "container",
1602
+ space: "equipment",
1603
+ externalId: "EquipmentData",
1604
+ },
1605
+ containerPropertyIdentifier: "manufacturer",
1606
+ },
1607
+ model: {
1608
+ container: {
1609
+ type: "container",
1610
+ space: "equipment",
1611
+ externalId: "EquipmentData",
1612
+ },
1613
+ containerPropertyIdentifier: "model",
1614
+ },
1615
+ installationDate: {
1616
+ container: {
1617
+ type: "container",
1618
+ space: "equipment",
1619
+ externalId: "EquipmentData",
1620
+ },
1621
+ containerPropertyIdentifier: "installationDate",
1622
+ },
1623
+ },
1624
+ },
1625
+ {
1626
+ space: "equipment",
1627
+ externalId: "Pump",
1628
+ version: "v1",
1629
+ name: "Pump",
1630
+ description: "Industrial pump with extended properties",
1631
+ implements: [
1632
+ {
1633
+ type: "view",
1634
+ space: "equipment",
1635
+ externalId: "BaseEquipment",
1636
+ version: "v1",
1637
+ },
1638
+ ],
1639
+ properties: {
1640
+ flowRate: {
1641
+ container: {
1642
+ type: "container",
1643
+ space: "equipment",
1644
+ externalId: "PumpSpecific",
1645
+ },
1646
+ containerPropertyIdentifier: "flowRate",
1647
+ name: "Flow Rate (L/min)",
1648
+ },
1649
+ headPressure: {
1650
+ container: {
1651
+ type: "container",
1652
+ space: "equipment",
1653
+ externalId: "PumpSpecific",
1654
+ },
1655
+ containerPropertyIdentifier: "headPressure",
1656
+ name: "Head Pressure (bar)",
1657
+ },
1658
+ efficiency: {
1659
+ container: {
1660
+ type: "container",
1661
+ space: "equipment",
1662
+ externalId: "PumpSpecific",
1663
+ },
1664
+ containerPropertyIdentifier: "efficiency",
1665
+ name: "Efficiency (%)",
1666
+ },
1667
+ },
1668
+ filter: {
1669
+ equals: {
1670
+ property: ["node", "type"],
1671
+ value: { space: "types", externalId: "Pump" },
1672
+ },
1673
+ },
1674
+ },
1675
+ {
1676
+ space: "maintenance",
1677
+ externalId: "MaintenanceEvent",
1678
+ version: "v1",
1679
+ name: "Maintenance Event",
1680
+ description: "Maintenance performed on equipment",
1681
+ properties: {
1682
+ scheduledDate: {
1683
+ container: {
1684
+ type: "container",
1685
+ space: "maintenance",
1686
+ externalId: "MaintenanceData",
1687
+ },
1688
+ containerPropertyIdentifier: "scheduledDate",
1689
+ },
1690
+ completedDate: {
1691
+ container: {
1692
+ type: "container",
1693
+ space: "maintenance",
1694
+ externalId: "MaintenanceData",
1695
+ },
1696
+ containerPropertyIdentifier: "completedDate",
1697
+ },
1698
+ cost: {
1699
+ container: {
1700
+ type: "container",
1701
+ space: "maintenance",
1702
+ externalId: "MaintenanceData",
1703
+ },
1704
+ containerPropertyIdentifier: "cost",
1705
+ name: "Cost (USD)",
1706
+ },
1707
+ notes: {
1708
+ container: {
1709
+ type: "container",
1710
+ space: "maintenance",
1711
+ externalId: "MaintenanceData",
1712
+ },
1713
+ containerPropertyIdentifier: "notes",
1714
+ },
1715
+ },
1716
+ },
1717
+ ]);
1718
+
1719
+ // 5. Create data model
1720
+ console.log("Creating data model...");
1721
+ await client.dataModels.upsert([
1722
+ {
1723
+ space: "industrial",
1724
+ externalId: "EquipmentMaintenance",
1725
+ name: "Equipment Maintenance Model",
1726
+ description: "Model for equipment and maintenance management",
1727
+ version: "v1",
1728
+ views: [
1729
+ {
1730
+ type: "view",
1731
+ space: "equipment",
1732
+ externalId: "Pump",
1733
+ version: "v1",
1734
+ },
1735
+ {
1736
+ type: "view",
1737
+ space: "maintenance",
1738
+ externalId: "MaintenanceEvent",
1739
+ version: "v1",
1740
+ },
1741
+ ],
1742
+ },
1743
+ ]);
1744
+
1745
+ // 6. Create type nodes
1746
+ console.log("Creating type nodes...");
1747
+ await client.instances.upsert({
1748
+ items: [
1749
+ {
1750
+ instanceType: "node",
1751
+ space: "types",
1752
+ externalId: "Pump",
1753
+ },
1754
+ ],
1755
+ });
1756
+
1757
+ // 7. Create pump instances
1758
+ console.log("Creating pump instances...");
1759
+ const pumps = await client.instances.upsert({
1760
+ items: [
1761
+ {
1762
+ instanceType: "node",
1763
+ space: "assets",
1764
+ externalId: "pump-001",
1765
+ type: { space: "types", externalId: "Pump" },
1766
+ sources: [
1767
+ {
1768
+ source: {
1769
+ type: "view",
1770
+ space: "equipment",
1771
+ externalId: "Pump",
1772
+ version: "v1",
1773
+ },
1774
+ properties: {
1775
+ serialNumber: "P2024-001",
1776
+ manufacturer: "FlowTech Industries",
1777
+ model: "FT-5000",
1778
+ installationDate: "2024-01-15T10:00:00Z",
1779
+ flowRate: 500.0,
1780
+ headPressure: 10.5,
1781
+ efficiency: 85.0,
1782
+ },
1783
+ },
1784
+ ],
1785
+ },
1786
+ {
1787
+ instanceType: "node",
1788
+ space: "assets",
1789
+ externalId: "pump-002",
1790
+ type: { space: "types", externalId: "Pump" },
1791
+ sources: [
1792
+ {
1793
+ source: {
1794
+ type: "view",
1795
+ space: "equipment",
1796
+ externalId: "Pump",
1797
+ version: "v1",
1798
+ },
1799
+ properties: {
1800
+ serialNumber: "P2024-002",
1801
+ manufacturer: "FlowTech Industries",
1802
+ model: "FT-3000",
1803
+ installationDate: "2024-02-01T14:30:00Z",
1804
+ flowRate: 300.0,
1805
+ headPressure: 8.0,
1806
+ efficiency: 82.0,
1807
+ },
1808
+ },
1809
+ ],
1810
+ },
1811
+ ],
1812
+ });
1813
+
1814
+ // 8. Create maintenance events as edges
1815
+ console.log("Creating maintenance events...");
1816
+ await client.instances.upsert({
1817
+ items: [
1818
+ {
1819
+ instanceType: "edge",
1820
+ space: "maintenance",
1821
+ externalId: "maint-001",
1822
+ type: { space: "relationships", externalId: "hasMaintenanceEvent" },
1823
+ startNode: { space: "assets", externalId: "pump-001" },
1824
+ endNode: { space: "maintenance", externalId: "event-001" },
1825
+ sources: [
1826
+ {
1827
+ source: {
1828
+ type: "view",
1829
+ space: "maintenance",
1830
+ externalId: "MaintenanceEvent",
1831
+ version: "v1",
1832
+ },
1833
+ properties: {
1834
+ scheduledDate: "2024-03-01T08:00:00Z",
1835
+ completedDate: "2024-03-01T12:00:00Z",
1836
+ cost: 1250.0,
1837
+ notes: "Routine maintenance and seal replacement",
1838
+ },
1839
+ },
1840
+ ],
1841
+ },
1842
+ ],
1843
+ });
1844
+
1845
+ // 9. Query data using the model
1846
+ console.log("Querying pump data with maintenance history...");
1847
+ const queryResult = await client.instances.query({
1848
+ with: {
1849
+ pumps: {
1850
+ nodes: {
1851
+ filter: {
1852
+ and: [
1853
+ {
1854
+ equals: {
1855
+ property: ["node", "type"],
1856
+ value: { space: "types", externalId: "Pump" },
1857
+ },
1858
+ },
1859
+ {
1860
+ range: {
1861
+ property: ["pump", "efficiency"],
1862
+ gte: 80.0,
1863
+ },
1864
+ },
1865
+ ],
1866
+ },
1867
+ },
1868
+ },
1869
+ maintenance: {
1870
+ edges: {
1871
+ from: "pumps",
1872
+ type: { space: "relationships", externalId: "hasMaintenanceEvent" },
1873
+ direction: "outwards",
1874
+ },
1875
+ },
1876
+ },
1877
+ select: {
1878
+ pumps: {
1879
+ sources: [
1880
+ {
1881
+ source: {
1882
+ type: "view",
1883
+ space: "equipment",
1884
+ externalId: "Pump",
1885
+ version: "v1",
1886
+ },
1887
+ properties: [
1888
+ "serialNumber",
1889
+ "manufacturer",
1890
+ "model",
1891
+ "flowRate",
1892
+ "efficiency",
1893
+ ],
1894
+ },
1895
+ ],
1896
+ },
1897
+ maintenance: {
1898
+ sources: [
1899
+ {
1900
+ source: {
1901
+ type: "view",
1902
+ space: "maintenance",
1903
+ externalId: "MaintenanceEvent",
1904
+ version: "v1",
1905
+ },
1906
+ properties: ["scheduledDate", "completedDate", "cost", "notes"],
1907
+ },
1908
+ ],
1909
+ },
1910
+ },
1911
+ });
1912
+
1913
+ console.log("Query results:");
1914
+ console.log(`Found ${queryResult.items.pumps.length} efficient pumps`);
1915
+ queryResult.items.pumps.forEach((pump) => {
1916
+ console.log(`\nPump: ${pump.externalId}`);
1917
+ console.log(
1918
+ `- Serial: ${pump.properties?.equipment?.Pump?.serialNumber}`
1919
+ );
1920
+ console.log(
1921
+ `- Efficiency: ${pump.properties?.equipment?.Pump?.efficiency}%`
1922
+ );
1923
+ });
1924
+
1925
+ // 10. Aggregate maintenance costs
1926
+ console.log("\nAggregating maintenance costs...");
1927
+ const aggregation = await client.instances.aggregate({
1928
+ view: {
1929
+ type: "view",
1930
+ space: "maintenance",
1931
+ externalId: "MaintenanceEvent",
1932
+ version: "v1",
1933
+ },
1934
+ groupBy: ["notes"],
1935
+ aggregates: [
1936
+ { count: { property: "externalId" } },
1937
+ { sum: { property: "cost" } },
1938
+ { avg: { property: "cost" } },
1939
+ ],
1940
+ });
1941
+
1942
+ console.log("Maintenance cost summary:");
1943
+ aggregation.items.forEach((group) => {
1944
+ console.log(`- Count: ${group.aggregates[0].value}`);
1945
+ console.log(`- Total cost: $${group.aggregates[1].value}`);
1946
+ console.log(`- Average cost: $${group.aggregates[2].value}`);
1947
+ });
1948
+ } catch (error) {
1949
+ if (error instanceof CogniteError) {
1950
+ console.error(`CDF API Error ${error.status}: ${error.errorMessage}`);
1951
+ if (error.extra) {
1952
+ console.error("Details:", JSON.stringify(error.extra, null, 2));
1953
+ }
1954
+ } else {
1955
+ console.error("Unexpected error:", error);
1956
+ }
1957
+ }
1958
+ }
1959
+
1960
+ // Run the example
1961
+ buildIndustrialDataModel();
1962
+ ```
1963
+
1964
+ This example demonstrates:
1965
+
1966
+ - Creating spaces for logical organization
1967
+ - Creating containers to define physical storage
1968
+ - Building views with inheritance and property mapping
1969
+ - Composing data models from views
1970
+ - Creating nodes with typed properties
1971
+ - Establishing relationships using edges
1972
+ - Querying across related data
1973
+ - Aggregating instance data
1974
+ - Handling errors appropriately
1975
+
1976
+ ## Best Practices
1977
+
1978
+ 1. **Space Organization**
1979
+
1980
+ - Use meaningful space names that reflect organizational structure
1981
+ - Separate concerns (e.g., `equipment`, `maintenance`, `operations`)
1982
+ - Consider access control requirements when designing spaces
1983
+
1984
+ 2. **Container Design**
1985
+
1986
+ - Keep containers focused on a single concept
1987
+ - Use appropriate data types and constraints
1988
+ - Add indexes for frequently queried properties
1989
+ - Set sensible defaults and nullable flags
1990
+
1991
+ 3. **View Composition**
1992
+
1993
+ - Use inheritance to avoid duplication
1994
+ - Apply filters to create specialized views
1995
+ - Document views thoroughly with descriptions
1996
+ - Version views when making breaking changes
1997
+
1998
+ 4. **Data Model Structure**
1999
+
2000
+ - Group related views into cohesive data models
2001
+ - Version data models for application compatibility
2002
+ - Include all necessary views for a use case
2003
+ - Document the intended usage clearly
2004
+
2005
+ 5. **Instance Management**
2006
+
2007
+ - Use meaningful external IDs following a naming convention
2008
+ - Leverage node types for categorization
2009
+ - Model relationships explicitly as edges
2010
+ - Include metadata in properties for traceability
2011
+
2012
+ 6. **Query Optimization**
2013
+
2014
+ - Use filters to reduce result sets early
2015
+ - Leverage indexes in containers
2016
+ - Paginate large result sets with cursors
2017
+ - Select only needed properties
2018
+
2019
+ 7. **Error Handling**
2020
+ - Implement retry logic for transient failures
2021
+ - Handle version conflicts appropriately
2022
+ - Validate data before upserting
2023
+ - Log errors with context for debugging