cognite/dto/data_organization/
relationships.rs

1use serde::{Deserialize, Serialize};
2use serde_json::json;
3use serde_with::skip_serializing_none;
4
5use crate::sequences::Sequence;
6use crate::time_series::TimeSeries;
7use crate::{
8    CogniteExternalId, Identity, IntoPatch, IntoPatchItem, LabelsFilter, Partition, Patch, Range,
9    SetCursor, UpdateList, UpdateSet, UpdateSetNull, UpsertOptions, WithPartition,
10};
11
12use crate::{assets::Asset, events::Event, files::FileMetadata};
13
14#[derive(Serialize, Deserialize, Clone, Copy, Debug, Default)]
15#[serde(rename_all = "camelCase")]
16/// Vertex type for a relationship.
17pub enum RelationshipVertexType {
18    #[default]
19    /// Reference an asset
20    Asset,
21    /// Reference a time series.
22    TimeSeries,
23    /// Reference a file
24    File,
25    /// Reference an event.
26    Event,
27    /// Reference a sequence.
28    Sequence,
29}
30
31#[derive(Serialize, Deserialize, Debug)]
32#[serde(untagged)]
33/// The vertex of a relationship, with the referenced data.
34pub enum RelationshipVertex {
35    /// Asset vertex.
36    Asset(Asset),
37    /// Time series vertex.
38    TimeSeries(TimeSeries),
39    /// File vertex.
40    File(FileMetadata),
41    /// Event vertex.
42    Event(Event),
43    /// Sequence vertex.
44    Sequence(Sequence),
45}
46
47#[skip_serializing_none]
48#[derive(Serialize, Deserialize)]
49#[serde(rename_all = "camelCase")]
50/// A CDF relationship, defining a custom connection between two resources.
51pub struct Relationship {
52    /// Relationship external ID, must be unique within the project.
53    pub external_id: String,
54    /// External ID of the source resource.
55    pub source_external_id: String,
56    /// Type of the source resource.
57    pub source_type: RelationshipVertexType,
58    /// External ID of the target resource.
59    pub target_external_id: String,
60    /// Type of the target resource.
61    pub target_type: RelationshipVertexType,
62    /// Timestamp in milliseconds since epoch when this relationship becomes valid.
63    pub start_time: Option<i64>,
64    /// Timestamp in milliseconds since epoch when this relationship stops being valid.
65    pub end_time: Option<i64>,
66    /// Confidence value of the existence of the relationship, between 0.0 and 1.0.
67    /// Generated relationships provide a score of the likelihood of
68    /// the relationship existing. Relationships without a confidence value
69    /// can be interpreted at the discretion of each project.
70    pub confidence: Option<f32>,
71    /// Data set this relationship belongs to.
72    pub data_set_id: Option<i64>,
73    /// List of labels on this relationship.
74    pub labels: Option<Vec<CogniteExternalId>>,
75    /// Time this relationship was created, in milliseconds since epoch.
76    pub created_time: Option<i64>,
77    /// Time this relationship was last modified, in milliseconds since epoch.
78    pub last_updated_time: Option<i64>,
79    /// Source of this relationship, if requested.
80    pub source: Option<RelationshipVertex>,
81    /// Target of this relationship, if requested.
82    pub target: Option<RelationshipVertex>,
83}
84
85#[skip_serializing_none]
86#[derive(Serialize, Deserialize, Default)]
87#[serde(rename_all = "camelCase")]
88/// Create a new relationship.
89pub struct AddRelationship {
90    /// Relationship external ID, must be unique within the project.
91    pub external_id: String,
92    /// External ID of the source resource.
93    pub source_external_id: String,
94    /// Type of the source resource.
95    pub source_type: RelationshipVertexType,
96    /// External ID of the target resource.
97    pub target_external_id: String,
98    /// Type of the target resource.
99    pub target_type: RelationshipVertexType,
100    /// Timestamp in milliseconds since epoch when this relationship becomes valid.
101    pub start_time: Option<i64>,
102    /// Timestamp in milliseconds since epoch when this relationship stops being valid.
103    pub end_time: Option<i64>,
104    /// Confidence value of the existence of the relationship, between 0.0 and 1.0.
105    /// Generated relationships provide a score of the likelihood of
106    /// the relationship existing. Relationships without a confidence value
107    /// can be interpreted at the discretion of each project.
108    pub confidence: Option<f32>,
109    /// Data set this relationship belongs to.
110    pub data_set_id: Option<i64>,
111    /// List of labels on this relationship.
112    pub labels: Option<Vec<CogniteExternalId>>,
113}
114
115impl From<Relationship> for AddRelationship {
116    fn from(rel: Relationship) -> Self {
117        AddRelationship {
118            external_id: rel.external_id,
119            source_external_id: rel.source_external_id,
120            source_type: rel.source_type,
121            target_external_id: rel.target_external_id,
122            target_type: rel.target_type,
123            start_time: rel.start_time,
124            end_time: rel.end_time,
125            confidence: rel.confidence,
126            data_set_id: rel.data_set_id,
127            labels: rel.labels,
128        }
129    }
130}
131
132#[skip_serializing_none]
133#[derive(Serialize, Deserialize, Default, Clone)]
134#[serde(rename_all = "camelCase")]
135/// Update a relationship
136pub struct PatchRelationship {
137    /// Type of the source resource.
138    pub source_type: Option<UpdateSet<RelationshipVertexType>>,
139    /// External ID of the source resource.
140    pub source_external_id: Option<UpdateSet<String>>,
141    /// Type of the target resource.
142    pub target_type: Option<UpdateSet<RelationshipVertexType>>,
143    /// External ID of the target resource.
144    pub target_external_id: Option<UpdateSet<String>>,
145    /// Confidence value of the existence of the relationship, between 0.0 and 1.0.
146    /// Generated relationships provide a score of the likelihood of
147    /// the relationship existing. Relationships without a confidence value
148    /// can be interpreted at the discretion of each project.
149    pub confidence: Option<UpdateSetNull<f32>>,
150    /// Timestamp in milliseconds since epoch when this relationship becomes valid.
151    pub start_time: Option<UpdateSetNull<i64>>,
152    /// Timestamp in milliseconds since epoch when this relationship stops being valid.
153    pub end_time: Option<UpdateSetNull<i64>>,
154    /// Data set this relationship belongs to.
155    pub data_set_id: Option<UpdateSetNull<i64>>,
156    /// List of labels on this relationship.
157    pub labels: Option<UpdateList<CogniteExternalId, CogniteExternalId>>,
158}
159
160impl IntoPatch<Patch<PatchRelationship>> for Relationship {
161    fn patch(self, options: &UpsertOptions) -> Patch<PatchRelationship> {
162        Patch::<PatchRelationship> {
163            id: Identity::ExternalId {
164                external_id: self.external_id,
165            },
166            update: PatchRelationship {
167                source_type: self.source_type.patch(options),
168                source_external_id: self.source_external_id.patch(options),
169                target_type: self.target_type.patch(options),
170                target_external_id: self.target_external_id.patch(options),
171                confidence: self.confidence.patch(options),
172                start_time: self.start_time.patch(options),
173                end_time: self.end_time.patch(options),
174                data_set_id: self.data_set_id.patch(options),
175                labels: self.labels.patch(options),
176            },
177        }
178    }
179}
180
181impl IntoPatch<PatchRelationship> for AddRelationship {
182    fn patch(self, options: &UpsertOptions) -> PatchRelationship {
183        PatchRelationship {
184            source_type: self.source_type.patch(options),
185            source_external_id: self.source_external_id.patch(options),
186            target_type: self.target_type.patch(options),
187            target_external_id: self.target_external_id.patch(options),
188            confidence: self.confidence.patch(options),
189            start_time: self.start_time.patch(options),
190            end_time: self.end_time.patch(options),
191            data_set_id: self.data_set_id.patch(options),
192            labels: self.labels.patch(options),
193        }
194    }
195}
196
197impl From<Relationship> for Patch<PatchRelationship> {
198    fn from(rel: Relationship) -> Self {
199        IntoPatch::<Patch<PatchRelationship>>::patch(rel, &Default::default())
200    }
201}
202
203#[derive(Serialize, Deserialize, Debug, Clone)]
204#[serde(rename_all = "camelCase")]
205pub(crate) struct RetrieveRelationshipsRequest {
206    pub items: ::serde_json::Value,
207    pub ignore_unknown_ids: bool,
208    pub fetch_resources: bool,
209}
210
211impl<T: Serialize> From<&Vec<T>> for RetrieveRelationshipsRequest {
212    fn from(items: &Vec<T>) -> RetrieveRelationshipsRequest {
213        RetrieveRelationshipsRequest {
214            items: json!(items),
215            ignore_unknown_ids: true,
216            fetch_resources: false,
217        }
218    }
219}
220
221impl<T: Serialize> From<&[T]> for RetrieveRelationshipsRequest {
222    fn from(items: &[T]) -> RetrieveRelationshipsRequest {
223        RetrieveRelationshipsRequest {
224            items: json!(items),
225            ignore_unknown_ids: true,
226            fetch_resources: false,
227        }
228    }
229}
230
231#[derive(Serialize, Debug, Clone)]
232#[serde(rename_all = "camelCase")]
233/// Filter on a relationship source or target.
234pub struct SourceOrTargetFilter {
235    /// Relationship vertex type.
236    pub r#type: RelationshipVertexType,
237    /// External ID of the resource.
238    pub external_id: String,
239}
240
241#[skip_serializing_none]
242#[derive(Serialize, Default, Debug, Clone)]
243#[serde(rename_all = "camelCase")]
244/// Filter relationships.
245pub struct RelationshipsFilter {
246    /// Include relationships that have any of these values as their `source_external_id`.
247    pub source_external_ids: Option<Vec<String>>,
248    /// Include relationships that has any of these values as their `source_type`.
249    pub source_types: Option<Vec<RelationshipVertexType>>,
250    /// Include relationships that have any of these values as their `target_external_id`.
251    pub target_external_ids: Option<Vec<String>>,
252    /// Include relationships that has any of these values as their `target_type`.
253    pub target_types: Option<Vec<RelationshipVertexType>>,
254    /// Include relationships that belongs to any of these data sets.
255    pub data_set_ids: Option<Vec<Identity>>,
256    /// Range of timestamps for `start_time`.
257    pub start_time: Option<Range<i64>>,
258    /// Range of timestamps for `end_time`.
259    pub end_time: Option<Range<i64>>,
260    /// Range of values for `confidence`.
261    pub confidence: Option<Range<f64>>,
262    /// Range of timestamps for `last_updated_time`.
263    pub last_updated_time: Option<Range<i64>>,
264    /// Range of timestamps for `created_time`.
265    pub created_time: Option<Range<i64>>,
266    /// Limits results to those active within the specified time range, that is,
267    /// if there is any overlap in the intervals `[activeAtTime.min, activeAtTime.max]`
268    /// and `[startTime, endTime]`, where both intervals are inclusive.
269    /// If a relationship does not have a startTime, it is regarded as active
270    /// from the beginning of time by this filter. If it does not have an `endTime`
271    /// is is regarded as active until the end of time. Similarly,
272    /// if a min is not supplied to the filter, the min is implicitly
273    /// set to the beginning of time. If a max is not supplied, the max is
274    /// implicitly set to the end of time.
275    pub active_at_time: Option<Range<i64>>,
276    /// Include relationships that match any of the resources in either their source-
277    /// or target-related fields.
278    pub sources_or_targets: Option<Vec<SourceOrTargetFilter>>,
279    /// Include relationships that match these label constraints.
280    pub labels: Option<LabelsFilter>,
281}
282
283#[skip_serializing_none]
284#[derive(Serialize, Default, Clone)]
285#[serde(rename_all = "camelCase")]
286/// Query for filtering relationships.
287pub struct FilterRelationshipsQuery {
288    /// Relationship filter.
289    pub filter: RelationshipsFilter,
290    /// Maximum number of relationships to return, default 100, maximum 1000.
291    pub limit: Option<u32>,
292    /// Cursor for pagination.
293    pub cursor: Option<String>,
294    /// Whether to fetch the associated resources.
295    pub fetch_resources: Option<bool>,
296    /// Split the data set into partitions.
297    pub partition: Option<Partition>,
298}
299
300impl SetCursor for FilterRelationshipsQuery {
301    fn set_cursor(&mut self, cursor: Option<String>) {
302        self.cursor = cursor;
303    }
304}
305
306impl WithPartition for FilterRelationshipsQuery {
307    fn with_partition(&self, partition: Partition) -> Self {
308        Self {
309            filter: self.filter.clone(),
310            limit: self.limit,
311            cursor: None,
312            fetch_resources: self.fetch_resources,
313            partition: Some(partition),
314        }
315    }
316}