> For the complete documentation index, see [llms.txt](https://documentation.ardoq.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://documentation.ardoq.com/data-model/fields/calculated-fields.md).

# Calculated Fields

Visualize more complex properties of your data by creating fields with values derived from the graph.

Calculated fields in Ardoq make it possible to collect and process information across everything you have documented in Ardoq. They allow you to store the result as a field value on components and references. The calculated field value is read-only but it behaves like any other field in Ardoq. They can be used for filtering, grouping, and conditional formatting.

For example, in our Application Portfolio Management module, we use a calculated field to weight and sum the six underlying dimensions for business and technical fit into two dimensions for display in a Gartner TIME quadrant.

All calculations are scheduled to run hourly. You can also trigger calculations manually via the:

* Gremlin editor&#x20;
  * Go to organization menu > **Admin** > **Metamodel** > **Fields** tab, select a field, and click the **Recalculate field** button near the Gremlin Editor.
* [Ardoq API](https://developer.ardoq.com/)

## Creating a Calculated Field

{% hint style="info" %}
**Considerations before creating a calculated field**

* Calculated fields use Gremlin graph queries.
  * Ensure you have the **Create Gremlin queries** privilege enabled for your role.
* Read our [Graph Search](/advanced-features/gremlin-graph-search.md) article to understand the basics of graph traversal.
* Since calculated fields are based on graph queries, and these have access to the whole graph, you need to be an Ardoq admin user to configure calculated fields.
  {% endhint %}

{% stepper %}
{% step %}

### Create the Field

From the main menu, go to organization menu > **Admin** > **Metamodel** > **Fields** tab.

Click **Create field** then name your field and give it a type.

Under **Transformations and Gremlin**, select **Gremlin query** from the dropdown. The default Gremlin query displayed will be a generic query for fetching all components and showing their ID, name, and who created them.

<figure><img src="https://2484004798-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FnlnB7uZ29iLVLzqGbCym%2Fuploads%2F0AziQp0lt9YZZ9UNTx15%2Fimage.png?alt=media&amp;token=5d3944cb-43db-43b8-9312-0fdbaee75576" alt=""><figcaption></figcaption></figure>
{% endstep %}

{% step %}

### Edit the Gremlin Query

Click the <i class="fa-expand">:expand:</i> (expand) icon to see the Gremlin editor, where you can edit your query and test it against your real data with the **Check syntax** button.

Click **Save** to save your calculated field, which will&#x20;

{% hint style="info" %}
We recommend using an LLM for quickly creating Gremlin queries and verifying the results in the editor.
{% endhint %}
{% endstep %}
{% endstepper %}

## Example Queries

The example below uses a function to calculate risk, using an existing `risk factor` value for components:

```groovy
def riskCalculator = {
  component = it.get()
  if (component.property("risk_factor").isPresent()) {
    component.property("risk_factor").value() > 5 ? "high" : "low"
  } else { 
    "none"
  }
}

g.V().hasId(ids)
.project('id', 'name', 'value')
.by(id)
.by('name')
.by(map(riskCalculator))
```

The following example aggregates cost one level up to the components that the calculated field applies to (in this case we set the field to apply to Applications) and showing graph traversals can be performed:

```groovy
g.V().hasId(ids)
  project('id', 'name', 'value').
    by(id).
    by('name').
    by(inE().hasLabel('Relates to').otherV().values("cost").sum())
```

The following example provides a more flexible query that traverses the graph, **collecting the cost of all components encountered along the way**. Here we only go in one reference-direction, meaning components must have an outgoing reference **towards** the component that has this calculated field:

```groovy
g.V().hasId(ids)
  project('id', 'name', 'value').
  by(id).
  by('name').
  by(emit().repeat( // Emit includes all components encountered
    inE().otherV()
    ).timeLimit(1000).dedup() // remove duplicate components
    .values("cost").sum() // sum up cost of all found components
  )
```

The following is an example of a calculated URL field. Its value will be a URL that is the same as the URL of the component overview page in Ardoq.

```groovy
g.V().hasId(ids)
  project('id', 'name', 'value').
    by(id).
    by('name').
    by(map{'https://myenvironment.ardoq.com/app/component-overview/' + it.get().id()})
```

You will just need to make sure to change `myenvironment.ardoq.com` to your own organization's domain.

## Frequently Asked Questions

<details>

<summary><strong>What is the <code>ids</code> value used for?</strong></summary>

The `ids` value is automatically generated and contains the unique ids of all components and/or references that the calculated field applies to. This means that you can modify the field so that it applies to a different set of references or components, without modifying the query.

</details>

<details>

<summary><strong>Why are my calculated fields not showing in the editor/views?</strong></summary>

This is likely because of values returned by the query. Calculated number fields, for example, expects a number to be returned. For instance, this query for a calculated number will fail when it returns a text value of `high`:

```
[
  {"id": "fb3f69b7798", "value": 1234}, <--- OK, NUMBER 👍
  {"id": "86e95ce6b5c", "value": "high"}, <--- NOT A NUMBER 👎
]
```

Ensure all values returned by the query match the field type (calculated **number**, calculated **text**, calculated **date time**, calculated **checkbox (boolean)**).

</details>

<details>

<summary><strong>Can I re-use the calculated field?</strong></summary>

By re-use, we mean modifying the field to apply to new component or reference types.&#x20;

This is possible, but if you want to do so, **you must ensure that the query is not too specific**. For example, if the query is written to traverse the graph via specific reference types, the query might not work for other component types that don't have connections using the same reference type.

</details>

<details>

<summary><strong>Why is my calculated query missing/deleted?</strong></summary>

If the field the calculated query is connected to is removed, the query will also be deleted.

</details>
