Skip to content

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:

  1. If NO reference is matched then a new reference will be created.
  2. If EXACTLY ONE reference is matched then that reference will be updated.
  3. 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:

["customFields.<custom_field_name>", "source.rootWorkspace"]

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").

["source", "type"]

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.

["target", "type"]

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:

["source", "target", "type"]

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:

{
  "references": {
    "delete": [
      {"id": "a0099b8d499b5d0001d84920"}
    ]
  }
}

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}}
    ]
  }
}
This differs from aliases that must match exactly one entity.

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.