Missing field values
Typically seen as an error saying that "The property does not exist as the key has no associated value for the provided element":
This error often occurs when using Calculated Fields, and is because one of the "by-steps" are pointing to a missing value. For example, there might be many applications that do not yet have a value set for "criticality".
The coalesce-step can help us provide a fallback-value in case the gremlin traverser does not find any results:
Bonus: Missing extra values when using project
A variant of this issue can also be seen when the project-step is used to show all applications and their referenced components. This query uses coalesce to add a fallback, but the problem now is that only one referenced component is shown!
In cases where we expect multiple values, we can skip the "coalesce-step" and instead use the "fold-step" to collapse all the gremlin traversal results into one list:
Gremlin is case-sensitive
If your query is not returning the expected results, make sure to double-check your predicates! Both component types, reference types and field values must have the correct capitalization.
For example, this query will return zero results:
g.V().hasLabel('application').has('criticality', 'high')
While this one returns 19 results after capitalizing 'Application'
and 'High'
:
g.V().hasLabel('Application').has('criticality', 'High')
Reserved keywords
Typically seen as an error about an "unexpected token":
Workaround
To avoid this issue, we can make sure reserved keywords such as in
is invoked as a step by adding __.
in front. Think of __ as a way to force the code interpreter back to the traversal context, so that it treats the reserved Groovy-keywords as gremlin steps:
g.V().filter(
__.in('ardoq_parent')
)
Why does this happen?
Gremlin queries are written in the Java-based Groovy programming language, which lets us write small snippets of code to do things like listing all components and their children by name in a comma-separated list (using the join-function):
g.V().has('name').project('name', 'children').
by('name').
by(coalesce(__.in('ardoq_parent').values('name').fold().map{it.get().join(', ')}, constant('')))
But because Groovy is the language powering our Gremlin queries, we sometimes bump into issues with "unexpected tokens".
Writing g.V().in('ardoq_parent')
to find all components that are children of another component will work just fine because the "in"-step is invoked as a function (notice the dot in front of in
), but using filtering to find all components that have children will cause an error:
g.V().filter( in('ardoq_parent'))
This is because when in
is not preceded by a dot, Groovy will now interpret the in-step as the reserved keyword in
. This is known as the Membership Operator in Groovy which can be used to see if a value exists in a collection:
'i am here' in ['one', 'two', 'three', 'i am here', 'four']
=> true
The following keywords are typically affected when missing a dot (.
) in front, and must be preceded by __.
:
in
not
as
Missing dots causing unexpected results
Unlike many programming languages, the Groovy language does not require a symbol to indicate the end of a statement. This however means that when a query stretches across multiple lines, we need to make sure there aren't missing dots that cause the statement to be accidentally split into two separate statements!
variable1 = 1
variable2 = 2; // <-- semicolon is optional!
Spot the difference?
This issue can also lead to the "reserved keyword"-issue making a return!
Field names are not the same as field "labels"
When looking up the value for a field, remember to use the field's "api-name"! The typical rule is that the field's api-name is the same as it's display name, but in lower case and with underscores replacing spaces. If in doubt, you can find the field api-name in the sidebar or in the "Manage Organization Fields" dialog:
Sub-queries must be terminated to avoid errors
When writing multiple queries, we need to make sure that the graph traversal has terminated. Here's an example where not terminating the sub-query to produce a valid list for the within-predicate means we get zero results:
// Find all components that have a parent with the following ids
g.V().has('parent', within(
// Find all capabilities that do not have parent and list their ids
g.V().hasLabel('Business Capability').not(out('ardoq_parent')).id()
))
In the above example, we need to terminate the query using one of the "Terminal steps" Gremlin provides. In our case, we will use toList
:
// Find all components that have a parent with the following ids
g.V().has('parent', within(
// Find all capabilities that do not have parent and list their ids
g.V().hasLabel('Business Capability').not(out('ardoq_parent')).id().toList()
))