All versions of this manual
X
 

Queries: Creating queries

Creating queries

Query language

Queries in Linkurious Enterprise are written using a graph query language. Linkurious Enterprise supports several graph databases: Neo4j, Memgraph, Neptune and Cosmos DB. Neo4j and Memgraph support the Cypher query language while Cosmos DB support the Gremlin query language.

Neptune now supports both Gremlin and Cypher, giving you the flexibility to choose the query language that best fits your needs. When querying Neptune, you can easily select which query language to use based on your preferences. Below is a screenshot showing how to pick the query language when querying Neptune:

query editor languages

The Cypher query language is similar to SQL, it can be learned from Neo4j's online documentation.

Access Rights for queries

There are four levels of access rights associated with queries in Linkurious Enterprise.

Access Right Level Description
Cannot run queries User can not create or run queries
Can run existing queries User can execute any existing query that has been shared with them. User can not create new queries.
Can create read-only queries and run existing queries User can execute any existing query that has been shared with them. User can not create queries that will alter the data (a.k.a. write-queries).
Can create read/write queries and run existing queries User can execute any existing query that has been shared with them. User can create queries.
Can manage, create read/write queries and run queries User can execute, edit and delete any existing query that has been shared with as least 1 group. This includes hidden queries.

The above access rights are applied to groups. The group a user belongs to defines their query access rights.

Writing queries

A query can have dynamic inputs (e.g. {{"Country":string:["France","Germany"]}}) that are used to parameterize the query. When a query has dynamic input, it will require the input to be provided to run. Query inputs can be of different types, such as nodes, edges, text, numbers, etc.

If a query creates, deletes or updates the graph, it is called a write-query. Creating a write-queries is subject to the user's access rights.

A query must return nodes and edges. Any other value return by the query (numbers, text) will be ignored.

Query creation

The query creator is where users can create, test and save new queries. It can be accessed by clicking on the {🖊} icon in the top-left of a visualization. The Query creator menu is split in two parts:

  • The upper part is where users can write their query using the graph query language.
  • The lower part is where users can preview the results of their query.

Accessing the query editor

Cypher query autocompletion

The query editor helps you create queries using the autocompletion for the Cypher query language. The Cypher autocompletion is aware of the schema and depending on the user's action suggests node categories, edge types or Cypher keywords.

  • Cypher's keywords have menu completion

keywords autocompletion

  • When the user types Variable + colon the Node Categories menu appears

Node's Categories autocompletion

  • When the user types Variable + colon the Edge Types menu appears

Edge's Types autocompletion

Saving a query

When users have written, tested and perfected a query, they can save it for later use in the next step by selecting NEXT. When saving a query, the user is prompted for a Query title, a Description, Tags and Sharing settings.

Query tags make queries easier to find after creation. When saving a query, you can add one or more existing tags to it and create new ones.

  • Created tags will be visible by any user who can create or edit queries.
  • All users who can edit a query can also add or remove tags for that query.
  • Query tags are saved on a datasource level. This means that each datasource will have different tags.
  • Query tags will be given a color automatically by Linkurious Enterprise.

Adding and creating tags when saving a query

Queries can be kept private, shared with everybody or shared specific user groups. Some important information on shared queries:

  • The description of a query can be seen by everyone who has access to it.
  • Only the creator of a query can edit and delete it.

Saved queries can be consulted from the right panel of the workspace.

Examples of queries

The section below provides examples of different types of queries that users can create and use.

Read-only query without input

The following query returns all City nodes that have between 3 and 100 Company nodes connected to them via HAS_CITY edges:

MATCH (city:City)<-[hasCity:HAS_CITY]-(company:Company)
WITH
  city,
  count(company) as score,
  collect(company) as companies,
  collect(hasCity) as hasCities
WHERE score > 3 AND score < 100
RETURN city, companies, hasCities

Running standard queries

Write-query with input

The following query changes the profession of a person and adds some change logs in a property:

MATCH (n)
WHERE ID(n) = {{"Suspicious entity":node:["Person"]}}
WITH 
  n,
  apoc.date.currentTimestamp() AS currentTimestamp
SET n.change_log = 
    "Modification done by: " + {{"User":env:"email"}} +
    " on: " + toString(datetime({epochMillis: currentTimestamp})) + 
    ". Previous value: " + n.profession + 
    ". Comment: " + {{"Comment":string:{"placeholder": "Add a note..."}}}
SET n.profession = {{"Profession":string}}
RETURN n;

Queries that write in the database can be shared with any user group, including those that were not granted "Write" permissions on any node category. Be considerate as to who you share queries with, and who has the right to share queries (see "Access Right" section in administration manual).

Single-node query

The following query returns up to max nodes of type COMPANY that are neighbours of the input node:

MATCH (n)-[edge]-(company:Company)
WHERE id(n) = {{"Node":node}}
RETURN edge, company
LIMIT {{"max":number:10}}

Running a query with input

Single-node queries can be run on multiple nodes at once, the same way it is possible to expand multiple nodes at once.

Two-nodes query

The following query is a built-in query that finds the shortest path between two nodes:

MATCH (a), (b), p = allShortestPaths((a)-[*..{{"Maximum path length":number:{"default": 4, "min": 1, "max": 10}}}]-(b)) 
WHERE id(a) = {{"Source":node}} AND id(b) = {{"Target":node}} 
RETURN p LIMIT {{"Maximum number of paths":number:{"default": 5, "min": 1, "max": 50}}}

Running shortest path query

Multiple-nodes query

The following query returns only the nodes that are shared neighbours to each and every node of the input nodeset:

MATCH (n) WHERE id(n) IN {{"My nodes":nodeset}}
MATCH (n)-[e]-(m)
WITH m, collect(e) AS edges, count(distinct n) AS sharedNeighborCount
WHERE sharedNeighborCount = size({{"My nodes":nodeset}})
RETURN m, edges

running a query with a nodeset input

Single-edge query

The following query returns all the parallel edges of the selected node:

MATCH (a)-[e]->(b) WHERE id(e) in {{"edge":edge}}
MATCH (a)-[e2]->(b)
RETURN a, e2, b

running a query with an edge input

Multiple-edges query

The following query returns only the edges that share a node with the edgeset input:

MATCH (n)-[e:INVESTED_IN]-() WHERE id(e) IN {{"My edges":edgeset}}
MATCH (n)-[e2:INVESTED_IN]-(m) 
RETURN e, e2, n, m

running a query with an edgeset input

Query input syntax

This section provides a deep-dive into the different types of input variables can be used in queries.

To declare inputs in a query, use double curly braces to mark the start and end of input, for example:

MATCH (n)-[e]-(m) WHERE id(n) = {{"My node":node}} RETURN e, m

An input variable is made of 3 terms separated by a colon (:), the first 2 being mandatory:

  • Variable ID (mandatory). A quoted string. It serves as the label of the input in the user form. It allows you to reuse the same variable in multiple places in your code.
  • Variable type (mandatory). Must be one of node, nodeset, edge, edgeset, string, number, date, datetime, enum, env, list.
  • Variable parameters (optional). Variable-specific parameters.

A Query requiring input can take both graph and non-graph input:

  • Node variables (node or nodeset)
  • Edge variables (edge or edgeset)
  • Non-graph variables (e.g. number, string, etc.)

node variable

Used to inject a single node ID in a graph query:

  • Keyword: node.
  • Parameters:
    • categories (optional): string or array of strings restricting the availability of input to the specified categories (as a consequence, the query will show in the context menu only if the selected node has one of the specified categories).

Examples:

  • {{"my node":node:"COMPANY"}}
  • {{"my node":node:["COMPANY","SUPPLIER"]}}
  • {{"my node":node:{"categories": ["COMPANY","SUPPLIER"]}}}

nodeset variable

Used to inject a list of node IDs in a graph query:

  • Keyword: nodeset
  • Parameters:
    • categories (optional): Same as for node type.

Examples:

  • {{"my nodes":nodeset:"COMPANY"}}
  • {{"my nodes":nodeset:["COMPANY","SUPPLIER"]}}
  • {{"my nodes":nodeset:{"categories": ["COMPANY","SUPPLIER"]}}}

edge variable

Used to inject a single edge ID in a graph query:

  • Keyword: edge.
  • Parameters:
    • types (optional): string restricting the availability of the input to the specified categories (as a consequence, the query will show in the context menu only if the selected edge has the specified type).

Examples:

  • {{"My edge":edge:["INVESTED_IN"]}}
  • {{"My edge":edge:{"types": ["INVESTED_IN"]}}}

edgeset variable

Used to inject a list of edge IDs in a graph query:

  • Keyword: edgeset
  • Parameters:
    • types (optional): Same as for edge type.

Examples:

  • {{"My edges":edgeset:["INVESTED_IN"]}}
  • {{"My edges":edgeset:{"types": ["INVESTED_IN"]}}}

enum variable

Used to inject a string, numerical or boolean value in a graph query, from a list of choices:

  • Keyword: enum
  • Parameters:
    • values (required): An array of values to choose from or an array of value + label.
    • default (optional): A default value, must be one of the values

Examples:

  • {{"my enum":enum:["FR", "EN", "US"]}}
  • {{"my enum":enum:[1, 2, 3]}}
  • {{"my enum":enum:[true, false]}}
  • {{"my enum":enum:{"values": ["FR", "EN", "US"], "default": "EN"}}}
  • {{"my enum":enum:{"values": [{"label": "France", "value": "FR"}, {"label": "U.S.A", "value": "US"}]}}}

boolean variable

Used to inject a true/false value in a graph query:

  • Keyword: boolean
  • Parameters:
    • default (optional): A default value

Examples:

  • {{"my choice":boolean}}
  • {{"my choice":boolean:true}}
  • {{"my choice":boolean:{"default": true}}}

date variable

Used to inject a date-time in a graph query:

  • Keyword: date
  • Parameters:
    • format (required): The serialization format of the date in the query, must be one of:
      • native: serialized as a native Date database object
      • timestamp: serialized as a numerical Unix timestamp in seconds
      • timestamps-ms: serialized as a numerical Unix timestamp in milliseconds
      • iso: serialized as a "yyyy-mm-dd" string (same as yyyy-mm-dd)
      • yyyy-mm-dd: serialized as a "yyyy-mm-dd" string (same as iso)
      • dd/mm/yyyy: serialized as a "dd/mm/yyyy" string
      • mm/dd/yyyy: serialized as a "mm/dd/yyyy" string
    • default (optional): A default value (expressed in "yyyy-mm-dd" format)
    • min (optional): The minimum accepted value (expressed in "yyyy-mm-dd" format)
    • max (optional): The maximum accepted value (expressed in "yyyy-mm-dd" format)

Examples:

  • {{"my date":date:"yyyy-mm-dd"}}
  • {{"my date":date:{"format": "yyyy-mm-dd"}}}
  • {{"my date":date:{"format: "timestamp-ms", "min": "2018-01-02"}}}
  • {{"my date":date:{"format": "yyyy-mm-dd", "default": "2018-01-01"}}}
  • {{"my date":date:{"format": "native", "min": "1990-12-31", "max": "2018-12-31"}}}

datetime variable

Used to inject a date-time in a graph query:

  • Keyword: datetime
  • Parameters:
    • format (required): The serialization format of the date-time in the query, must be one of:
      • native: serialized as a native DateTime database object
      • timestamp: serialized as a numerical Unix timestamp in seconds
      • timestamps-ms: serialized as a numerical Unix timestamp in milliseconds
      • iso: serialized as a "yyyy-mm-ddThh:mm:ss" string
    • timezone (optional): A string in +HH:MM or -HH:MM format. If omitted and the format is "native', a LocalDateTime object is created.
    • default (optional): A default value (expressed in "yyyy-mm-ddThh:mm:ss" format)
    • min (optional): The minimum accepted value (expressed in "yyyy-mm-ddThh:mm:ss" format)
    • max (optional): The maximum accepted value (expressed in "yyyy-mm-ddThh:mm:ss" format)

Examples:

  • {{"my date-time":datetime:"native"}}
  • {{"my date-time":datetime:{"format": "native"}}}
  • {{"my date-time":datetime:{"format": "iso"}}}
  • {{"my date-time":datetime:{"format":"native", "min": "2017-01-02T10:10:10"}}}
  • {{"my date-time":datetime:{"format":"native", "min": "1940-01-01T00:00:00", "max": "2020-01-01T00:00:00", "default": "2000-01-01T00:00:00", "timezone":"+02:00"}}}

number variable

Used to inject a numerical value in a graph query:

  • Keyword: number
  • Parameters:
    • default (optional): A default value
    • placeholder (optional): The placeholder text to use in the form.
    • min (optional): The minimum accepted value
    • max (optional): The maximum accepted value

Examples:

  • {{"my number":number}}
  • {{"my number":number:12}}
  • {{"my number":number:{"default": 12}}}
  • {{"my number":number:{"min": 0}}}
  • {{"my number":number:{"min": 0, "max": 15.5, "default": 12}}}

string variable

Used to inject a string of text in a graph query:

  • Keyword: string
  • Parameters:
    • default (optional): A default value
    • placeholder (optional): The placeholder text to use in the form.

Examples:

  • {{"my string":string}}
  • {{"my string":string:"paris"}}
  • {{"my string":string:{"default": "paris"}}}
  • {{"my string":string:{"placeholder": "Enter a city"}}}

env variable

Used to inject information about the user who runs the query into a graph query:

  • Keyword: env
  • Parameters:
    • value: The type of value that will be injected into a graph query.
  • Allowed Values:
    • email: Used to inject email address of the user who runs the query.

Examples:

  • {{"User":env:{"value":"email"}}}
  • {{"User":env:"email"}}

list variable

Used to inject a string or numerical array in a graph query, from a list of choices with the possibility of making multiple choices:

  • Keyword: list
  • Parameters:
    • values (required): An array of values to choose from or an array of value + label.
    • default (optional): A default value array, must be a subset of the list elements.

Examples:

  • {{"my list":list:["FR", "EN", "TR"]}}
  • {{"my list":list:[1, 2, 3]}}
  • {{"my list":list:{"values": ["FR", "EN", "TR"], "default": ["EN"]}}}

Previewing and testing queries

Once users are satisfied with their query, they can preview the results of their query by clicking on the PREVIEW YOUR QUERY button. The preview allows users to visualize the results of their query and:

  • View the details of a node just like they can view details in the workspace;
  • Expand nodes to better understand the context and validate the result of the query. The original results have a blue halo to differentiate them from nodes added later on through the expand action;
  • Add the results of the query directly to the workspace without saving the query by clicking the Add results to the workspace button.

Previewing the result of a simple query

When a query contains input variables, a form is generated and displayed to the right of the query editor, allowing the query to be tested.

Previewing the result of a query with inputs

Write queries can not be tested.

Queries best practises

  1. If an input variable is followed directly by a closing curly brace character, users must add a space between the end of the input and the following closing curly brace character as shown in the example below.
    MATCH (n:PERSON)-[:HAS_ACCOUNT]->(b:BANK {name: {{"name":string}} })
    RETURN n, b
    
  2. For Cypher: Any query containing the CALL statement will be evaluated based on the access mode (for more info, refer to Neo4j documentation) of called procedure. The query will either be allowed or denied, depending on the access mode of the query and the access right of the user.
    • Queries that include a call to any procedure with modes DEFAULT and READ are considered READ queries in Linkurious Enterprise.
    • Queries that include a call to any procedure with other modes such as DBMS, WRITE, SCHEMA are considered WRITE queries in Linkurious Enterprise.
  3. Queries can require a lot of computing resources from the database. Make sure to test your queries properly, and verify that you have enough computing power before sharing them. If overloaded, your database server may run slow or even crash, making the database unavailable.