Manipulating the graph: Queries and templates
In this chapter, we will learn how to use queries and query templates:
- Running standard queries
- Running query templates
- Managing queries and templates
- Sharing queries and templates
- Creating a standard query
- Creating a query template
- Access-rights considerations
Most graph databases support a query language that can be used to express pattern queries in the graph. For example, Neo4j supports Cypher and CosmosDB supports Gremlin.
The Cypher query language is similar to SQL, it can be learned from Neo4j's online documentation.
Running standard queries
Standard queries can be executed from the Query Management panel, that can be opened using the Magic wand icon in the top left corner of the workspace.
The following query returns all the cities that are connected to at least 3 companies and at most 100.
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
Note that the Cypher query has to contain a RETURN statement.
Only nodes and edges returned are displayed.
Returned values that are not a node or an edge (such as the score
in the previous example) are not displayed.
Running query templates
- A Query Template is a query that accepts variables.
- Query templates can be executed from the context menu (right-click) of a node
- When user input is required, a form is displayed to the user
The following template returns, in the limit of "max", the "COMPANY" neighbours of the parameter node.
MATCH (n)-[edge]-(company:Company)
WHERE id(n) = {{"Node":node}}
RETURN edge, company
LIMIT {{"max":number:10}}
A query template accepts several types of variables:
- Node / Node set
- Edge / Edge set
- Text
- Number
- Enumeration (one value among a list of predefined choices, e.g. a country from a predefined list of countries)
- Date / Date-time
- Boolean (True / False)
- Env ("email")
- List
Single-node query templates can be run on multiple nodes at once, the same way it is possible to expand multiple nodes at once.
Managing queries and templates
The Query Management panel is opened through the "Magic Wand" icon in the workspace. It contains 3 tabs:
- Standard Queries: list of all queries owned by and shared with the user
- Query Templates: list of all templates owned by and shared with the user
- Query Editor: create, test and save queries and templates
A user can view the details, execute and load in the editor:
- The queries and templates he created (identified as "Not shared" if not shared, "Shared with groups: ‘X’ and ‘Y’" if shared with user groups X and Y)
- The queries and templates that were shared with them (identified "Shared with me")
- The built-in templates
A user can edit and delete:
- The queries and templates he created
Sharing queries and templates
Queries and Templates can be shared:
- With everybody
- With a selection of user groups
Queries and Templates can require a lot of computing resources from the database. Make sure to test your queries and templates 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, and Linkurious Enterprise unusable.
Creating a standard query
The Query Editor provides a place to create and validate queries before saving them.
The Preview allows to visualize the results of a query:
- View the details of a node like 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.
- You can add the results of the query directly to the workspace, without saving the query by clicking "Add results to the workspace" at the bottom right
Creating a query template
A Template is a mix of code (Cypher or Gremlin) and placeholders for variables. The way to declare the variables is inspired by the "Mustache" templating language, using the double curly braces to mark the start and end of a variable declaration.
Example:
MATCH (n)-[e]-(m) WHERE id(n) = {{"My node":node}} RETURN e, m
Testing templates in the editor
When a Template variable is detected, a form is generated and displayed to the right of the query editor, allowing the template to be tested.
Query templates syntax
A 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 Template can be made of:
- Node variables (
node
ornodeset
) - Edge variables (
edge
oredgeset
) - Non-graph variables (e.g.
number
,string
, etc.)
When a Query Template consists of at least one node or edge variable, it is available through both the context menu and the Query Management panel.
When a Query Template consists of non-graph variables only, it is available through the Query Management panel only.
Single-node templates
When a query template that consist of one node
variable and any number of non-graph variables:
- it is available in the node context-menu (i.e. node right-click menu)
- when there is a node-category restriction, the template is only available for nodes matching the constraint
Two-nodes templates
- It is possible to use up to two
node
variables in a Template. - The Template is available from the context menu when exactly two nodes are selected.
- The Shortest Path is now a built-in Template with two nodes variables (source and target).
Multi-nodes templates
- There is a specific type of variable for multiple nodes:
nodeset
- This variable accepts selections of 1, 2 or more nodes
- This variable should be used when you want your Template to accept an undetermined number of nodes as input.
E.g. the following Template 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 = length({{"My nodes":nodeset}})
RETURN m, edges
Single-edge templates
When a query template that consist of one edge
variable and any number of non-graph variables:
- it is available in the edge context-menu (i.e. edge right-click menu)
- when there is an edge type restriction, the template is only available for edges matching the constraint
Multi-edge templates
- There is a specific type of variable for multiple edges:
edgeset
- This variable accepts selections of 1, 2 or more edges
- This variable should be used when you want your Template to accept an undetermined number of edges as input.
E.g. the following Template returns only the edges that share a node with the input edgeset:
MATCH (n)-[e:INVESTED_IN]-() WHERE id(e) in {{"My edges":edgeset}}
match (n)-[e2:INVESTED_IN]-(m)
return e, e2, n, m
Query templates variable types
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 the template to the specified categories (as a consequence, the Template will show in the context menu only if the selected node has one of the specified categories).
Examples:
{{"my node":node:"COMPANY"}}
(shorthand for category parameter){{"my node":node:["COMPANY","SUPPLIER"]}}
(shorthand for category parameter){{"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 fornode
type.
Examples:
{{"my nodes":nodeset:"COMPANY"}}
(shorthand for category parameter){{"my nodes":nodeset:["COMPANY","SUPPLIER"]}}
(shorthand for category parameter){{"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 template to the specified categories (as a consequence, the Template will show in the context menu only if the selected edge has the specified type).
Examples:
{{"My edge":edge:["INVESTED_IN"]}}
(shorthand for type parameter){{"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 foredge
type.
Examples:
{{"My edges":edgeset:["INVESTED_IN"]}}
(shorthand for type parameter){{"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 thevalues
Examples:
{{"my enum":enum:["FR", "EN", "US"]}}
(shorthand for values){{"my enum":enum:[1, 2, 3]}}
(shorthand for values){{"my enum":enum:[true, false]}}
(shorthand for values){{"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}}
(shorthand for default value){{"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 nativeDate
database objecttimestamp
: serialized as a numerical Unix timestamp in secondstimestamps-ms
: serialized as a numerical Unix timestamp in millisecondsiso
: serialized as a "yyyy-mm-dd" string (same asyyyy-mm-dd
)yyyy-mm-dd
: serialized as a "yyyy-mm-dd" string (same asiso
)dd/mm/yyyy
: serialized as a "dd/mm/yyyy" stringmm/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)
Example:
{{"my date":date:"yyyy-mm-dd"}}
(shorthand for format){{"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 nativeDateTime
database objecttimestamp
: serialized as a numerical Unix timestamp in secondstimestamps-ms
: serialized as a numerical Unix timestamp in millisecondsiso
: 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', aLocalDateTime
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)
Example:
{{"my date-time":datetime:"native"}}
(shorthand for format){{"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 valueplaceholder
(optional): The placeholder text to use in the form.min
(optional): The minimum accepted valuemax
(optional): The maximum accepted value
Example:
{{"my number":number}}
{{"my number":number:12}}
(shorthand for default value){{"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 valueplaceholder
(optional): The placeholder text to use in the form.
Example:
{{"my string":string}}
{{"my string":string:"paris"}}
(shorthand for default value){{"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 graphy query.
- Allowed Values:
email
: Used to inject email address of the user who runs the query.
Example:
{{"User":env:{"value":"email"}}}
{{"User":env:"email"}}
(shorthand for value)
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 thelist
elements.
Example:
{{"my list":list:["FR", "EN", "TR"]}}
(shorthand for values){{"my list":list:[1, 2, 3]}}
(shorthand for values){{"my list":list:{"values": ["FR", "EN", "TR"], "default": ["EN"]}}}
Access-rights considerations
There are 4 levels of permission associated with the queries and templates:
Cannot run queries
- No permissions to create nor run queries/templates
Can run existing queries
:- Permission to execute any existing query/template that has been shared with them (This includes write queries/templates)
- No permission to access the Editor and create new queries/templates
Can create read-only queries and run existing queries
- Permission to execute any existing query/template that has been shared with them (This includes write queries/templates)
- Permission to access the Editor and create new read-only queries/templates and share them with other users
- No permission to create new read/write queries/templates
Can create read/write queries and run existing queries
- Permission to execute any existing query/template that has been shared with them (This includes write queries/templates)
- Permission to access the Editor and create new read-only queries/templates and share them when other users
- permission to create new read/write queries/templates and share then with other users
For Cypher: Any query or template containing the
CALL
statement will be evaluated based on the access mode (for more info, refer to documentation) of called procedure. A query or template will either be allowed or denied, depending on the access mode of the query/template and the access right of the user.
- Queries or templates that include a call to any procedure with modes 'DEFAULT' and 'READ' are considered as READ queries in Linkurious Enterprise.
- Queries or templates that include a call to any procedure with other modes such as 'DBMS', 'WRITE', 'SCHEMA' are considered as WRITE queries in Linkurious Enterprise.
Queries and templates 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)