Warning
You are viewing documentation for a feature that is currently under incubation. This means that the feature is not yet fully supported and may change or be removed in future versions. This documentation is provided for early adopters and testers. Features under incubation should not be used in production environments.
Operations on References
Upsert
Warning
Upsert operations on references may not be mixed with create, update or delete operations on references in the same request.
The upsert operation uses the subset of properties listed in the uniqueBy
list to match against references in Ardoq. The following rules apply:
- If NO reference is matched then a new reference will be created.
- If EXACTLY ONE reference is matched then that reference will be updated.
- If MORE THAN ONE reference is matched then the request will fail.
The body
of the upsert operation is the same as the create
operation and (unlike update operations) must contain the source
, target
and type
fields. Note that the source
and target
fields may any of the Identifier types.
A batchId
may be provided to identify the reference being upserted.
By Custom Field
Gotcha
The string "source.rootWorkspace
" must be included in the uniqueBy
list when identifying references by custom field, not "rootWorkspace
". This is because the rootWorkspace
is not included in the body
of the reference and is derived from the source
field.
In order to identify a reference by a custom field, you must provide the the following strings (in any order) in the uniqueBy
list:
Where <custom_field_name>
is the name of the custom field that you want to use to uniquely identify the reference.
If a reference with a custom field that matches the value under body.customFields.<custom_field_name>
already exists in the workspace that the body.source
component belongs to then it will be updated. If no such reference exists then a new reference will be created.
{
"references": {
"upsert": [
{
"batchId": "Y",
"uniqueBy": ["customFields.ref_id", "source.rootWorkspace"],
"body": {
"source": "6509b612499b5d0001d84921",
"target": "4b131856bb51f7fa1aace0db",
"type": 2,
"customFields": {"ref_id": "XYZ"}
}
}
]
}
}
By Source and Type
Sometimes you have a component that should be the source of at most one reference of a given type. For example a component of type Employee
might be expected to have exactly one Office
location with the relation "works at"
.
Using this example, by specifying the source
and type
as unique we can create a new reference "works at" from an Employee to an Office. If the Employee already "works at" an Office, then we will update the value of the Office (target) to ensure that they work at the correct location.
Info
The choice between source+type
or target+type
will depend on your relationship. For example "A is managed by B" suggests that the "A" is the source of at most one reference to another component (in this case "B"), whereas "A manages B" implies that "B" is the target of at most one reference from another component (in this case "A").
If a reference with a source that matches the value under body.source
a type that matches the value under body.type
already exists then it will be updated. If no such reference exists then a new reference will be created.
In other words, this lets you ensure that there is only one reference of a certain type that uses a source component. When the upsert operation is an update
this has the effect of "re-using" the reference but altering the target component. In the location example, this would mean that only one "works at" relation would exist, but the location might change based on the body.target
value.
{
"references": {
"upsert": [
{
"uniqueBy": ["source", "type"],
"body": {
"source": "6509b612499b5d0001d84921",
"target": "4b131856bb51f7fa1aace0db",
"type": 99
}
}
]
}
}
By Target and Type
Sometimes you have a component that should be the target of at most one reference of a given type. For example a Manager
can manage multiple members of a team but a TeamMember
can be managed by at most one manager.
Using this example, by specifying the target
and type
as unique we can create a new reference "manages" from a Manager to an TeamMember. If a Manager already "manages" an TeamMember, then we will update the value of the Manager (source) to ensure that the TeamMember has the correct manager.
If a reference with a target that matches the value under body.target
a type that matches the value under body.type
already exists then it will be updated. If no such reference exists then a new reference will be created.
{
"references": {
"upsert": [
{
"uniqueBy": ["target", "type"],
"body": {
"source": "6509b612499b5d0001d84921",
"target": "4b131856bb51f7fa1aace0db",
"type": 99
}
}
]
}
}
By Source, Target and Type
In order to identify a reference by source, target and type, you must provide the the following strings (in any order) in the uniqueBy
list:
If a reference with a source that matches the value under body.source
a target that matches the value under body.target
and a type that matches the value under body.type
already exists then it will be updated. If no such reference exists then a new reference will be created.
In other words, this lets you ensure that there is only one reference of a certain type between two components which can be useful in many cases.
{
"references": {
"upsert": [
{
"uniqueBy": ["source", "target", "type"],
"body": {
"source": "6509b612499b5d0001d84921",
"target": "4b131856bb51f7fa1aace0db",
"type": 2
}
}
]
}
}
Create
Warning
Create operations on references may not be mixed with upsert operations on references in the same request.
{
"references": {
"create": [
{
"body": {
"source": "6509b612499b5d0001d84921",
"target": "4b131856bb51f7fa1aace0db",
"type": 2
}
}
]
}
}
In the same way that a component may have its body.parent
field set to an Identifier, a reference may have its body.source
and body.target
(both of which are components) set. In this example we use an Alias to identify the source and a Batch Id to identify the target.
{
"aliases": {
"components": {
"A": {"name": "A", "rootWorkspace": "c253c98231776d0c8a54879e"},
}
},
"components": {
"create": [
{
"batchId": "B",
"body": {
"rootWorkspace": "c253c98231776d0c8a54879e",
"typeId": "p1024822409134",
"name": "B",
}
},
]
},
"references": {
"create": [
{
"body": {
"source": "A",
"target": "B",
"type": 2
}
}
]
}
}
Update
Warning
Update operations on references may not be mixed with upsert operations on references in the same request.
In order to update a reference you must be able to identify it using either its Ardoq OID or an Alias. The body.source
and body.target
fields may be set to the Identifier of a component.
Update the reference identified by an Ardoq OID
{
"references": {
"update": [
{
"id": "a0099b8d499b5d0001d84920",
"ifVersionMatch": "latest",
"body": {
"displayText": "Updated Reference"
}
}
]
}
}
Update the reference identified using an Alias and set the target to a component identified using an Alias
{
"aliases": {
"components": {
"A": {"name": "A", "rootWorkspace": "c253c98231776d0c8a54879e"},
"B": {"name": "B", "rootWorkspace": "c253c98231776d0c8a54879e"},
"C": {"name": "C", "rootWorkspace": "c253c98231776d0c8a54879e"},
},
"references": {
"A-2-B": {"source": "A", "target": "B", "type": 2}
}
},
"references": {
"update": [
{
"id": "A-2-B",
"ifVersionMatch": "latest",
"body": {
"target": "C"
}
}
]
}
}
Delete
In order to delete a reference you must be able to first identify it.
By Ardoq OID
If you know the Ardoq OID of the reference that you wish to delete, then you can include it directly. For example, in order to delete a reference with the ID "a0099b8d499b5d0001d84920
" you would include the following:
By Alias
If you can uniquely identify the reference using a combination of fields, then you can use an alias in place of an id. In this example, we know that there is exactly one reference with the provided source, target and type:
{
"aliases": {
"components": {
"A": {"name": "A", "rootWorkspace": "c253c98231776d0c8a54879e"},
"B": {"name": "B", "rootWorkspace": "c253c98231776d0c8a54879e"}
},
"references": {
"A->B": {"source": "A", "target": "B", "type": 2}
}
},
"references": {
"delete": [
{"id": "A->B"}
]
}
}
By Match
Deleting by match is the most powerful way of deleting references from Ardoq.
A match is an object with a single key "match" whose value is identical to that of an alias . However, unlike aliases and the uniqueBy
of an upsert a match object is expected to correspond to zero or more references. Thus, in the following example will delete ANY reference that has a source component uniquely identified by {"name": "A", "rootWorkspace": "c253c98231776d0c8a54879e"}
and type 2
; be that zero, one or more.
{
"aliases": {
"components": {
"A": {"name": "A", "rootWorkspace": "c253c98231776d0c8a54879e"}
}
},
"references": {
"delete": [
{"match": {"source": "A", "type": 2}}
]
}
}
The following table covers the combinations of fields that can be used to identify a reference in a match object.
rootWorkspace | type | source | target | customFields.<X> |
---|---|---|---|---|
✅ | ||||
✅ | ✅ | |||
✅ | ✅ | |||
✅ | ✅ | |||
✅ | ✅ | |||
✅ | ✅ | ✅ |
Dependencies
One important aspect of deleting by match is that references that are dependencies of a Batch request WILL NOT be deleted. Intuitively this means that you can not delete references that you are creating/updating/upserting at the same time.
- Every created reference is a dependency.
- Every updated reference is a dependency.
- Every upserted reference is a dependency.