Ardoq Graph Search uses the Gremlin graph traversal language.

Table of Contents:

  • General References on Gremlin
  • Ardoq Graph Search Examples
  • Tips & Tricks for writing more effectful queries

General References on Gremlin

For non-ardoq specific reference guides to Gremlin, we recommend the two sources below, please keep in mind that they are linking to external resources.

Ardoq Graph Search Examples

Below you will find some Ardoq specific Gremlin queries to get you started with solving business questions with Ardoq Graph Search.

What is the overall cost of our application portfolio?

g.V().hasLabel('Application').
      values('cost').
      sum()


What is the overall target cost of our application portfolio?

g.V().hasLabel('Application').
      values('target_cost').
      sum()


Find all applications with no direct connection to capabilities

g.V().hasLabel('Application').
      not(
        both().
        hasLabel('Capability'))


What is the overall cost of all applications whose current lifecycle status is sunsetting?

g.V().hasLabel('Application').
      values('lifecycle_status', 'planned_sunset').
      values('cost').
      sum()


What is the total cost of the sunsetting applications?

g.V().hasLabel('Application').
      has('planned_sunset').
      values('cost').
      sum()


Show all capabilities which are realized by multiple applications

g.V().hasLabel('Capability').
      filter(__.in('Realized By').
                count().
                is(gt(1)))


Find all Capability level 3 which are missing a Delivered by reference to Business Process Level 1

g.V().hasLabel('Capability level 3').
      not(
        out('Triggering').
        hasLabel('Business Process Level 1'))


Show Capability, Application and Cost in a table

g.V().hasLabel('Capability').as('capability').
      out().hasLabel('Application').as('app').
      out().hasLabel('Licence').as('licence').
      select('capability', 'app', 'licence').
      by('name').by('name').by('cost')


Which applications have a select multiple list field “division” which contains “PFD”?

def containsPFD = {
  it.get().values('division').join(', ').contains('PFD')
}

g.V().hasLabel('Application').
      filter(containsPFD)


What is the average criticality score for the applications that are realized by the Product Portfolio Management capability?

g.V().has('name', 'Product Portfolio Management').
      both('Realized by').
      hasLabel('Application').
      values('criticality_number').
      mean()


Show the name of the task with the highest time spent

g.V().hasLabel('Task').
      order().
      by('minutes', decr).
      limit(1).
      values('name')


How many highly critical capabilities are dependent on high-risk applications?

g.V().hasLabel('Application').
      has('Risk', 'High').
      in('Depends on').
      hasLabel('Capability').
      has('criticality', 'High').
      count()


Show the time spent on work

/* Assumes a data model where there’s a task component type, with a parent component being a task category. We only want the sum of the hours for tasks belonging to a specific category */

g.V().has(
        'parent', within(
          g.V().has('name', 'Work').
          id().
          toSet())).
      values('hours').
      sum()


How many components in workspace A is any component in workspace B connected to on average?

/* If the answer is 3, then that means that on average, each component in workspace B is connected to 3 components in workspace A. We will assume that the id of workspace A is 3aa630a7a3a725a174aa0628 and the id of workspace B is b3b110bcbbb3902bb09b48bb */

g.V().has('rootWorkspace', 'b3b110bcbbb3902bb09b48bb').
      both().
      has('rootWorkspace', '3aa630a7a3a725a174aa0628').
      groupCount().
      by(id).
      select(values).
      unfold().
      mean()


Which high-risk capabilities are realized by high-risk applications?

/* Here, we consider a model where a capability might have different type names, like 'Capability level 1', 'Capability level 2'... We want to consider all components whose component type names include 'Capability' 
*/

def isCapability = {
 ((String) it.get().label()).contains('Capability')
}

g.V().hasLabel('Application').
      has('Risk', 'High').
      in('Realized by').
      filter(isCapability).
      has('criticality_list', 'high')


Which business process is impacted if Mongo-DB1 goes down?

g.V().hasLabel('Business process').
      filter(
        repeat(
          timeLimit(20).
          both().
          simplePath()).
        until(
          has('name', 'mongodb-1')))


Which business processes are affected by Salesforce sunsetting?

g.V().hasLabel('Business Process').
      filter(
        repeat(
          timeLimit(20).
          both().
          simplePath().
        until(
          has('name', 'Salesforce')))


List all applications in one column and their parents in another column. If they don’t have any parents, the parent cell will be empty.

g.V().hasLabel('Application').
      match(
        __.as('apps').values('name').as('Name'),
        __.as('apps').choose(
             has('parent'),
             values('parent').map({
               g.V(it.get()).next()}).values('name'),
               map({''})).
        as('Parent')).
      select('Name', 'Parent')


Find all applications which has no connection (direct or indirect) to capabilities.

g.V().hasLabel('Application').
      not(
        filter(
          repeat(
            timeLimit(20).
            both().
            simplePath()).
          until(
            hasLabel('Capability'))))


How many capabilities will be impacted by sunsetting applications in 2019?

def sunsetsIn2019 = {
  ((String) it.get().property('planned_sunset')).contains('2019')
}

g.V().or(
       hasLabel('Capability'),
       hasLabel('Strategy Capability')).
         filter(
           repeat(
           timeLimit(20).
           both().
           simplePath()).
         until(
           hasLabel('Application').
           has('planned_sunset').
           filter(sunsetsIn2019))
      ).count()

Tips and tricks

Working with relative dates

/* Define relative date variables - have in mind that only SECONDS and DAYS are supported ChronoUnits in the Groovy runtime environment */

today = new Date().toInstant()
fiveDaysFromNow = today.minus(5,java.time.temporal.ChronoUnit.DAYS).toString()

/* Filter on dates with steps such as has() and where() */
g.V().hasLabel('Application').
  has('last-updated', lte(fiveDaysFromNow))


Only consider components within a specific root workspace

/* Simply add the following filter */

.has('rootWorkspace', '<rootWorkspaceId>')

/* All applications */

g.V().hasLabel('Application')

/* All applications within the root workspace with id 59e884b41fa32c6dc6786176 */

g.V().hasLabel('Application').
      has('rootWorkspace', '59e884b41fa32c6dc6786176')


Only consider components within a parent workspace

/* Add the following filter */

.has('parent', '<parentWorkspaceId>')

/* All applications */

g.V().hasLabel('Application')

/* All applications within parent workspace with id 59524f229f2a2654e159d1c9 */

g.V().hasLabel('Application').
      has('parent', '59524f229f2a2654e159d1c9')


Show the traversed path

/* Simply add .path() to the end of the query. This requires that the original query ends on a component or a reference */

g.V().hasLabel('Application').
      outE('Runs on').
      inV().
      path()


Show multiple specific values from the results

/* Simply add the following to your result (if your result consists of components, and not references) */ 

.valuemap('<fieldName1>', '<fieldName2>'...)

/* All components named mongodb-1 */

g.V().has('name', 'mongodb-1')

/* Name and state of all components named mongodb-1 */

g.V().has('name', 'mongodb-1').
      valueMap('name', 'state')



How can I round down a decimal number?

g.V().hasLabel('Application').
      values('technical_fit').
      math('floor _ ')


How can I round up a decimal number?

g.V().hasLabel('Application').
      values('technical_fit').
      math('ceil _ ')


Access all the components in a traversal, and not just the “last” one

/* Simply add the following to the end of the query (this requires that the path does not include any explicit references (you should use .out() instead of .outE().inV()) Otherwise, you will end up with a collection which consists of both references and components, and then any operation which only works for only components or only references will fail) */

.path().unfold()

/* All components reached by outgoing references from the application called Excel */

g.V().hasLabel('Application').
      has('name', 'Excel').
      out()

/* Excel and all components reached by outgoing references from the application called Excel */

g.V().hasLabel('Application').
      has('name', 'Excel').
      out().
      path().
      unfold()
Did this answer your question?