Operators
Operators一览:
| 类别 | 支持 | 待支持 |
|---|---|---|
| General operators | DISTINCT, . for property access | [] for dynamic property access |
| Mathematical operators | +, -, *, /, %, ^ | |
| Comparison operators | =, <>, <, >, ⇐, >=, IS NULL, IS NOT NULL | |
| String-specific comparison operators | STARTS WITH, ENDS WITH, CONTAINS | |
| Boolean operators | AND, OR, XOR, NOT | |
| String operators | + for concatenation | |
| List operators | + for concatenation, IN to check existence of an element in a list, [] for accessing element(s) |
Clauses
简介
已支持的clauses如下:
| category | clause | remark |
|---|---|---|
Reading clauses | MATCH | 支持 |
OPTIONAL MATCH | 支持 | |
MANDATORY MATCH | 待支持 | |
Projecting clauses | RETURN … [AS] | 支持 |
WITH … [AS] | 支持 | |
UNWIND … [AS] | 支持 | |
Reading sub-clauses | WHERE | 支持 |
ORDER BY [ASC[ENDING] / DESC[ENDING]] | 支持 | |
SKIP | 支持 | |
LIMIT | 支持 | |
Writing clauses | CREATE | 支持 |
DELETE | 支持 | |
DETACH DELETE | 支持 | |
SET | 支持 | |
REMOVE | 支持 | |
Reading/Writing clauses | MERGE | 支持 |
CALL […YIELD] | 支持 | |
Set operations | UNION | 支持 |
UNION ALL | 待支持 |
MATCH
Basic node finding
✓ Get all nodes
MATCH (n) RETURN n
✓ Get all nodes with a label
MATCH (movie:Movie) RETURN movie.title
✓ Related nodes
MATCH (director {name: 'Oliver Stone'})-[]-(movie)RETURN movie.title
✓ Match with labels
MATCH (:Person {name: 'Oliver Stone'})-[]-(movie:Movie)RETURN movie.title
Relationship basics
✓ Outgoing relationships
MATCH (:Person {name: 'Oliver Stone'})-[]->(movie)RETURN movie.title
✓ Directed relationships and variable
MATCH (:Person {name: 'Oliver Stone'})-[r]->(movie)RETURN type(r)
✓ Match on relationship type
MATCH (wallstreet:Movie {title: 'Wall Street'})<-[:ACTED_IN]-(actor)RETURN actor.name
✓ Match on multiple relationship types
MATCH (wallstreet {title: 'Wall Street'})<-[:ACTED_IN|:DIRECTED]-(person)RETURN person.name
✓ Match on relationship type and use a variable
MATCH (wallstreet {title: 'Wall Street'})<-[r:ACTED_IN]-(actor)
RETURN r.role
Relationships in depth
❏ Relationship types with uncommon characters
MATCH (n {name: 'Rob Reiner'})-[r:`TYPE WITH SPACE`]->()RETURN type(r)
✓ Multiple relationships
MATCH (charlie {name: 'Charlie Sheen'})-[:ACTED_IN]->(movie)<-[:DIRECTED]-(director)RETURN movie.title, director.name
✓ Variable-length relationships
MATCH (martin {name: 'Charlie Sheen'})-[:ACTED_IN*1..3]-(movie:Movie)RETURN movie.title
❏ Relationship variable in variable-length relationships
MATCH p = (actor {name: 'Charlie Sheen'})-[:ACTED_IN*2]-(co_actor)RETURN relationships(p)
named pathsare not supported for now.❏ Match with properties on a variable-length path
MATCH p = (charlie:Person)-[* {blocked:false}]-(martin:Person)WHERE charlie.name = 'Charlie Sheen' AND martin.name = 'Martin Sheen'
RETURN p
✓ Zero-length paths
MATCH (wallstreet:Movie {title: 'Wall Street'})-[*0..1]-(x)RETURN x
✓ Named paths
MATCH p = (michael {name: 'Michael Douglas'})-[]->()RETURN p
✓ Matching on a bound relationship
MATCH (a)-[r]-(b)
WHERE id(r)= 0
RETURN a,b
Shortest path
✓ Single shortest path
MATCH (martin:Person {name: 'Martin Sheen'}), (oliver:Person {name: 'Oliver Stone'}),p = shortestPath((martin)-[*..15]-(oliver))
RETURN p
✓ All shortest paths
MATCH (martin:Person {name: 'Martin Sheen'}), (michael:Person {name: 'MichaelDouglas'}), p = allShortestPaths((martin)-[*]-(michael))
RETURN p
Get node or relationship by id
✓ Node by id
MATCH (n)
WHERE id(n)= 0
RETURN n
☒ Relationship by id
MATCH ()-[r]->()
WHERE id(r) = 0
RETURN r
✓ Multiple nodes by id
MATCH (n)
WHERE id(n) IN [0, 3, 5]
RETURN n
RETURN
✓ Return nodes
MATCH (n {name: 'B'}) RETURN nNote
Return
idof n.✓ Return relationships
MATCH (n {name: 'A'})-[r:KNOWS]->(c)RETURN r
Note
Return
<SRC_ID, DST_ID, EDGE_ID>of r.✓ Return property
MATCH (n {name: 'A'}) RETURN n.name❏ Return all elements
MATCH p = (a {name: 'A'})-[r]->(b)RETURN *
❏ Variable with uncommon characters
MATCH (`This isn\'t a common variable`)
WHERE `This isn\'t a common variable`.name = 'A'
RETURN `This isn\'t a common variable`.happy
✓ Aliasing a field
MATCH (a {name: 'A'})RETURN a.age AS SomethingTotallyDifferent
✓ Optional properties
MATCH (n) RETURN n.age
❏ Other expressions
MATCH (a {name: 'A'})RETURN a.age > 30, "I'm a literal", (a)-[]->()
(a)-[]->()not supported.✓ Unique results
MATCH (a {name: 'A'})-[]->(b)RETURN DISTINCT b
WHERE
Basic usage
✓ Boolean operations
MATCH (n)
WHERE n.name = 'Peter' XOR (n.age < 30 AND n.name = 'Tobias') OR NOT (n.name =
'Tobias' OR n.name = 'Peter')
RETURN n.name, n.age
✓ Filter on node label
MATCH (n)
WHERE n:Swedish
RETURN n.name, n.age
✓ Filter on node property
MATCH (n)
WHERE n.age < 30
RETURN n.name, n.age
✓ Filter on relationship property
MATCH (n)-[k:KNOWS]->(f)
WHERE k.since < 2000
RETURN f.name, f.age, f.email
❏ Filter on dynamically-computed property
WITH 'AGE' AS propname
MATCH (n)
WHERE n[toLower(propname)]< 30
RETURN n.name, n.age
✓ Property existence checking
MATCH (n)
WHERE exists(n.belt)
RETURN n.name, n.belt
String matching
✓ Match the beginning of a string
MATCH (n)
WHERE n.name STARTS WITH 'Pet'
RETURN n.name, n.age
✓ Match the ending of a string
MATCH (n)
WHERE n.name ENDS WITH 'ter'
RETURN n.name, n.age
✓ Match anywhere within a string
MATCH (n)
WHERE n.name CONTAINS 'ete'
RETURN n.name, n.age
✓ String matching negation
MATCH (n)
WHERE NOT n.name ENDS WITH 's'
RETURN n.name, n.age
Using path patterns in
WHERE✓ Filter on patterns
MATCH (tobias {name: 'Tobias'}), (others)WHERE others.name IN ['Andres', 'Peter'] AND (tobias)<-[]-(others)
RETURN others.name, others.age
✓ Filter on patterns using NOT
MATCH (persons), (peter {name: 'Peter'})WHERE NOT (persons)-[]->(peter)
RETURN persons.name, persons.age
✓ Filter on patterns with properties
MATCH (n)
WHERE (n)-[:KNOWS]-({name: 'Tobias'})RETURN n.name, n.age
using
exists().✓ Filter on relationship type
MATCH (n)-[r]->()
WHERE n.name='Andres' AND type(r) STARTS WITH 'K'
RETURN type(r), r.since
Lists
✓ IN operator
MATCH (a)
WHERE a.name IN ['Peter', 'Tobias']
RETURN a.name, a.age
Missing properties and values
✓ Default to false if property is missing
MATCH (n)
WHERE n.belt = 'white'
RETURN n.name, n.age, n.belt
✓ Default to true if property is missing
MATCH (n)
WHERE n.belt = 'white' OR n.belt IS NULL RETURN n.name, n.age, n.belt
ORDER BY n.name
✓ Filter on null
MATCH (person)
WHERE person.name = 'Peter' AND person.belt IS NULL RETURN person.name, person.age,
person.belt
Using ranges
✓ Simple range
MATCH (a)
WHERE a.name >= 'Peter'
RETURN a.name, a.age
✓ Composite range
MATCH (a)
WHERE a.name > 'Andres' AND a.name < 'Tobias'
RETURN a.name, a.age
SKIP
✓ Skip first three records
MATCH (n)
RETURN n.name
ORDER BY n.name
SKIP 3
✓ Return middle two records
MATCH (n)
RETURN n.name
ORDER BY n.name
SKIP 1
LIMIT 2
✓ Using an expression with SKIP to return a subset of the records
MATCH (n)
RETURN n.name
ORDER BY n.name
SKIP toInteger(3*rand())+ 1
LIMIT
✓ Return a subset of the records
MATCH (n)
RETURN n.name
LIMIT 3
✓ Using an expression with LIMIT to return a subset of the records
MATCH (n)
RETURN n.name
LIMIT toInteger(3 * rand())+ 1
CREATE
Create nodes
Note
TuGraph不支持创建空的nodes,不支持多labels。
☒ Create single node
CREATE (n)
☒ Create multiple nodes
CREATE (n), (m)
✓ Create a node with a label
CREATE (n:Person)
☒ Create a node with multiple labels
CREATE (n:Person:Swedish)
✓ Create node and add labels and properties
CREATE (n:Person {name: 'Andres', title: 'Developer'})✓ Return created node
CREATE (a {name: 'Andres'})RETURN a
Create relationships
✓ Create a relationship between two nodes
MATCH (a:Person), (b:Person)
WHERE a.name = 'Node A' AND b.name = 'Node B'
CREATE (a)-[r:RELTYPE]->(b)
✓ Create a relationship and set properties
MATCH (a:Person), (b:Person)
WHERE a.name = 'Node A' AND b.name = 'Node B'
CREATE (a)-[r:RELTYPE {name: a.name + '<->' + b.name}]->(b)✓ Create a full path
CREATE p = (andres {name:'Andres'})-[:WORKS_AT]->(neo)<-[:WORKS_AT]-(michael {name:'Michael'})
RETURN p
Use parameters with CREATE
❏ Create node with a parameter for the properties
CREATE (n:Person $props)
RETURN n
☒ Create multiple nodes with a parameter for their properties
UNWIND $props AS map
CREATE (n)
SET n = map
cannot create vertex without label.
CALL[…YIELD]
✓ Call a procedure using CALL
CALL db.labels
✓ View the signature for a procedure
CALL dbms.procedures() YIELD name, signature
WHERE name='dbms.listConfig'
RETURN signature
❏ Call a procedure using a quoted namespace and name
CALL `db`.`labels`
✓ Call a procedure with literal arguments
CALL org.opencypher.procedure.example.addNodeToIndex('users', 0, 'name')❏ Call a procedure with parameter arguments
CALL org.opencypher.procedure.example.addNodeToIndex($indexName,$node,$propKey)
❏ Call a procedure with mixed literal and parameter arguments
CALL org.opencypher.procedure.example.addNodeToIndex('users', $node, 'name')✓ Call a procedure with literal and default arguments
CALL org.opencypher.procedure.example.addNodeToIndex('users', 0)✓ Call a procedure within a complex query using CALL…YIELD
CALL db.labels() YIELD label
RETURN count(label) AS numLabels
✓ Call a procedure and filter its results
CALL db.labels() YIELD label
WHERE label CONTAINS 'User'
RETURN count(label) AS numLabels
❏ Call a procedure within a complex query and rename its outputs
CALL db.propertyKeys() YIELD propertyKey AS prop
MATCH (n)
WHERE n[prop] IS NOT NULL RETURN prop, count(n) AS numNodes
UNION
❏ Combine two queries and retain duplicates
MATCH (n:Actor)
RETURN n.name AS name
UNION ALL MATCH (n:Movie)
RETURN n.title AS name
✓ Combine two queries and remove duplicates
MATCH (n:Actor)
RETURN n.name AS name
UNION
MATCH (n:Movie)
RETURN n.title AS name
Functions
已支持的functions如下:
| category | function | remark |
|---|---|---|
Predicate functions | exists() | |
Scalar functions | id() | |
properties() | ||
head() | ||
last() | ||
toBoolean() | ||
toFloat() | ||
toInteger() | ||
type() | ||
label() | OpenCypher扩展方法 | |
Aggregating functions | avg() | |
collect() | ||
count() | ||
max() | ||
min() | ||
percentileCont() | ||
percentileDisc() | ||
stDev() | ||
stDevP() | ||
sum() | ||
List functions | keys() | |
labels() | 返回结果有且只有一个label | |
range() | ||
Mathematical functions | abs() | |
ceil() | ||
floor() | ||
rand() | ||
round() | ||
sign() | ||
String functions | / |
附录1. 语法扩充及不同
TuGraph对OpenCypher的扩充如下:
Planner hint
- USING START ON 指定起始点
MATCH (camelot:Film {title:'Camelot'})<-[:ACTED_IN]-(actor)-[]->(x)USING START ON camelot
RETURN x
TuGraph查询语言与OpenCypher的不同点如下:
Label数量
- TuGraph: Each node/relationship must have one and only one label. So error occurs when there is no label, and the 1st label will be picked as the label if there are more than one label.
- OpenCypher: One node/relationship may have 0 to many labels.
Label in NodePattern.
LightGraph: Label is necessary in NodePattern. e.g.
MATCH (tom:Person {name: 'Tom Hanks'}) RETURN tomOpenCypher: Label(s) are not necessary. e.g.
MATCH (tom {name: 'Tom Hanks'}) RETURN tom
Schema.
- TuGraph: TuGraph has strong schema
- OpenCypher: schema-less
附录2. 内置procedures列表
使用dbms.procedures()方法可以查看已安装LightGraph实例中的内置procedures列表.
内置procedures完整列表如下:
| Name | Description | Signature |
|---|---|---|
| db.labels | 列出所有Vertex Label | db.labels() :: (label::STRING) |
| db.relationshipTypes | 列出所有Edge Label | db.relationshipTypes() :: (relationshipType::STRING) |
| db.indexes | 列出所有索引 | db.indexes() :: (index::LIST) |
| db.propertyKeys | 列出所有的property keys | db.propertyKeys() :: (propertyKey::STRING) |
| db.warmup | 预热数据 | db.warmup() :: () |
| db.addLabel | 创建Vertex Label | db.addLabel(label_name::STRING |
| db.addType | 创建Edge Label | db.addType(type_name::STRING |
| db.addIndex | 创建索引 | db.addIndex(label_name::STRING |
| db.backup | 备份数据 | db.backup(destination::STRING) :: () |
| dbms.procedures | 列出所有procedures | dbms.procedures() :: (name::STRING |
| dbms.security.changePassword | 更改当前用户的密码 | dbms.security.changePassword(current_password::STRING |
| dbms.security.changeUserPassword | 更改指定用户的密码 | dbms.security.changeUserPassword(user_name::STRING |
| dbms.security.changeUserRole | 更改指定用户的角色 | dbms.security.changeUserRole(user_name::STRING |
| dbms.security.createUser | 创建用户 | dbms.security.createUser(user_name::STRING |
| dbms.security.deleteUser | 删除用户 | dbms.security.deleteUser(user_name::STRING) :: (success::BOOLEAN) |
| dbms.security.listUsers | 列出所有用户 | dbms.security.listUsers() :: (user_name::STRING |
| dbms.security.showCurrentUser | 列出当前用户信息 | dbms.security.showCurrentUser() :: (current_user::STRING) |
| dbms.security.accessPermission | 查询指定用户对指定子图的访问权限 | dbms.security.accessPermission(user_name::STRING |
| dbms.security.setAccessPermission | 设置指定用户对指定子图的访问权限 | dbms.security.setAccessPermission(user_name::STRING |
| dbms.security.deleteAccessPermission | 删除指定用户对指定子图的访问权限 | dbms.security.deleteAccessPermission(user_name::STRING |
| dbms.graph.createGraph | 创建子图 | dbms.graph.createGraph(graph_name::STRING, description::STRING, max_size_GB::INTEGER) :: (success::BOOLEAN) |
| dbms.graph.modGraph | 修改子图属性 | dbms.graph.modGraph(graph_name::STRING, config::MAP) :: (success::BOOLEAN) |
| dbms.graph.deleteGraph | 删除子图 | dbms.graph.deleteGraph(graph_name::STRING) :: (success::BOOLEAN) |
| dbms.graph.listGraphs | 列出所有子图 | dbms.graph.listGraphs() :: (graph_name::STRING |
| algo.shortestPath | 查询两个顶点间的最短路径 | algo.shortestPath(startNode::NODE |
| algo.allShortestPaths | 查询两个顶点间的所有最短路径 | algo.allShortestPaths(startNode::NODE |
| algo.native.extract | 查询指定VertexId/EdgeUid(列表)指定field的值(列表) | algo.native.extract(id::ANY |




