Cypher操作API
功能介绍
Cypher是一种被广泛使用的声明式图数据库查询语言,使用Cypher语句可以查询GES中的数据,并返回结果。当前的Cypher实现中使用了图的统计信息,目前Cypher查询编译过程中使用了基于label的点边索引,如需正常使用Cypher,请先参考Cypher预置条件构建索引。
URL
- URI 格式
POST /ges/v1.0/{project_id}/graphs/{graph_name}/action?action_id=execute-cypher-query
- 参数说明
表1 URI参数说明 参数
是否必选
类型
说明
project_id
是
String
项目编号,用于资源隔离。
graph_name
是
String
图名称。
请求
- 请求样例
POST http://{SERVER_URL}/ges/v1.0/{project_id}/graphs/{graph_name}/action?action_id=execute-cypher-query { "statements": [{ "statement": "match (n) return n limit 1", "parameters": {}, "resultDataContents": ["row"], "includeStats": false }] }
- 参数说明
表2 Body参数说明 参数
是否必选
类型
说明
statements
是
List
statements为一个语句组,包含一到多条语句。其中每个元素的格式如表 statements参数说明。
表3 statements参数说明 参数
是否必选
类型
说明
statement
是
String
Cypher语句。
parameters
是
Json
Cypher语句参数,在进行参数化查询时使用,默认为空。
如需使用,请参考参数化查询。
resultDataContents
否
String或List
返回的结果样式,样式可设置一个或多个。可选参数有“row”,”graph”, “raw”(2.2.27版本新增)。
includeStats
否
Boolean
控制返回结果是否携带增删改统计信息的开关,若不设置此字段,默认为不携带。
executionMode(2.2.23)
否
String
执行模式。同步执行模式填写“sync”,异步执行填写“async”,不写默认同步执行。异步模式下,获取查询结果参见查询Job状态。
limit(2.2.23)
否
Int
该字段仅在异步模式下生效,表示对异步结果的最大结果数限制,默认值为100000。
在异步模式(executionMode参数值为async)下,支持cypher查询结果以csv格式导出到文件(GES版本2.3.4及以上支持该功能),详情请参考导出job返回结果到文件。目前支持下列对象的返回:
- 点边单值属性、点边id、分组计数结果等值类型。
- 对于对象类型,目前的版本暂不支持导出,csv中视作空值处理。
响应
- 要素说明
表4 要素说明 参数
是否必选
类型
说明
results
是
List
一个List,每个元素是一条Cypher语句的返回结果。
errors
是
List
一个List,每个元素包含字符串形式的code和message信息。
表5 参数results中各要素说明 参数
是否必选
类型
说明
columns
是
List
返回的字段名。
data
是
List
返回的数据值,每个元素代表一条记录。
stats
否
Json
返回的增删改统计信息。
plan
否
Json
如果cypher语句带explain前缀,则此字段输出查询计划,否则不显示该字段,正常执行查询。
表6 参数data中各要素说明: 参数
是否必选
类型
含义
row
否
List
表示具体一行的内容,每个元素对应该行的一个字段,仅当resultDataContents为空或者包含“row”类型时显示。
meta
否
List
表示该行每个字段的类型信息,仅当resultDataContents为空或者包含“row”类型时显示。
graph
否
Json
以“graph”样式返回该行信息,仅当resultDataContents包含“graph”类型时显示。
raw(2.2.27)
否
List
以“raw”样式返回该行信息,仅当resultDataContents包含“raw”类型时显示。
- 同步任务请求成功样例
Http Status Code: 200 { "results": [ { "columns": ["n"], "data": [ { "row": [ { "occupation": "artist", "gender": "F", "Zip-code": "98133", "userid": 0, "age": "25-34" } ], "meta": [ { "id": "46", "type": "node", "labels": [ "user" ] } ] } ], "stats": { "contains_updates": false, "edges_created": 0, "edges_deleted": 0, "labels_set": 0, "properties_set": 0, "vertices_created": 0, "vertices_deleted": 0 } } ], "errors": [] }
表7 stats各要素响应参数: 参数
是否必选
类型
含义
contains_updates
是
Boolean
表示本次查询是否有数据修改
edges_created
是
Integer
创建的边数目
edges_deleted
是
Int
删除的边数目
labels_set
是
Integer
设置的label数目
properties_set
是
Integer
设置的属性数目
vertices_created
是
Integer
创建的点数目
vertices_deleted
是
Integer
删除的点数目
- 异步任务请求成功样例
Http Status Code: 200 { "results": [ { "columns": [ "jobId", "jobType" ], "data": [ { "row": [ "b64a5846-e306-4f87-b0f1-d595ee2a9910", 1 ], "meta": [ null, null ] } ] } ], "errors": [] }
- 请求失败样例
Http Status Code: 400 { "results": [], "errors": [ { "code": "GES.8904", "message": "Label index in vertices is not found." } ] }
返回值
- 正常
200
- 异常
表8 异常返回值说明 返回值
说明
400 Bad Request
请求错误。
401 Unauthorized
鉴权失败。
403 Forbidden
没有操作权限。
404 Not Found
找不到资源。
500 Internal Server Error
服务内部错误。
503 Service Unavailable
服务不可用。
Cypher预置条件
图规格为一千亿边的图暂无此约束。
当前的Cypher查询编译过程中使用了基于label的点边索引,如需正常使用Cypher,请使用新建索引API构建索引,示例如下:
- 点label索引添加命令示例
POST http://{SERVER_URL}/ges/v1.0/{project_id}/graphs/{graph_name}/indices { "indexName": "cypher_vertex_index", "indexType": "GlobalCompositeVertexIndex", "hasLabel": "true", "indexProperty": [] }
- 边label索引添加命令示例
POST http://{SERVER_URL}/ges/v1.0/{project_id}/graphs/{graph_name}/indices { "indexName": "cypher_edge_index", "indexType": "GlobalCompositeEdgeIndex", "hasLabel": "true", "indexProperty": [] }
- 需要同时添加两个索引(点label索引和边label索引)才能正常使用Cypher查询。
- 不需要构建的情况:如果图中已经存在hasLabel为true, indexProperty为空的点索引或边索引,则不需要重复构建。
- 添加索引API为异步接口,查询索引是否添加成功,请使用查询Job状态API。
基本操作
操作名 |
Cypher语句 |
---|---|
查点 |
match (n) return n |
查边 |
match (n)-[r]->(m) return n, r, m |
查路径 |
match (n:user)-[r]->(m:movie)-->(s:series) return n,r,m,s |
过滤查询 |
match(n:user) where n.userid>=5 return n |
分组聚集 |
match(n:movie) return n.genres, count(*) |
去重 |
match(n:movie) return distinct n.genres |
排序 |
match(n:movie) return n order by n.movieid |
创建点 |
create (n:user{userid:1}) return n |
创建边 |
match (n:user{userid:15}),(m:movie{movieid:10}) create (n)-[r:rate]->(m) |
删除点 |
match (n:user{userid:1}) delete n |
更改标签 |
match (n:user{userid:1}) set n:movie return n |
更改属性 |
match (n:user{userid:1}) set n.userid=2 return n |
Cypher实现的兼容性
- Cypher支持的子句列表
Cypher实现了若干子句,通过对子句进行组合可以实现丰富的查询语义,进而完成点边过滤、多跳查询、排序去重、分组聚集等诸多能力。目前GES支持的Cypher子句如下:
表9 Cypher支持的子句清单 子句
支持情况
举例
match
部分支持
match (n:movie) return n
return
支持
return [1,2,3] as p
with
支持
match (n) with labels(n) as label, count(*) as count
where count > 10 return *
where
支持
match (n:movie) where n.movieid > 10 return n
order by
支持
match (n:movie) return n order by n.genres
skip
支持
match (n:movie) return n order by n.genres skip 5
limit
支持
match (n:movie) return n order by n.genres skip 5 limit 10
create
支持
create (n:user{_ID_: 'Jack' }) return n
delete
支持
match (n:movie)<-[r]-(m:user) delete r
set
支持
match (n:user{userid:0}) set n.gender='M' return n
call procedures
支持
call db.schema()
unwind
支持
unwind [1, 2, 3] as p return p
union
支持
match (n:movie) return id(n) union match (n:user) return id(n)
说明:union仅在百亿以下规格图中支持(不包含百亿)。
- 目前暂不支持merge、foreach、optional等操作,暂不支持使用Cypher语句增删索引。
- 由于GES的元数据不是Schema Free的,点边label属性等有严格的限制,因此不支持Remove操作。
- Order by子句不支持List类型的排序,当属性值的Cardinality不为single时,排序结果未知。
- 参数化查询支持
Cypher支持参数化的查询。通过把查询语句中的数值、字符串等值类型提取为参数,加速查询的编译时间,提高查询速度。
以下提供几种参数化查询的示例:
- 参数化查询请求示例1:
POST http://{SERVER_URL}/ges/v1.0/{project_id}/graphs/{graph_name}/action?action_id=execute-cypher-query { "statements": [{ "statement": " match (n:user) where n.occupation = $occupation return n", "parameters": { "occupation" : "artist" }, "resultDataContents": ["row"] }] }
- 参数化查询请求示例2:
POST http://{SERVER_URL}/ges/v1.0/{project_id}/graphs/{graph_name}/action?action_id=execute-cypher-query { "statements": [{ "statement": " match (n:user {`Zip-code`:'98133'}) set n = $props return n", "parameters": { "props": { "gender": "M", "age": "56+" } }, "resultDataContents": ["row"] }] }
参数化查询不适用于以下场景,下列查询语句均无法正常执行:
- 属性键值,如:match (n) where n.$param = 'something'
- 点边标签,如:match (n:user) set n:$code
- 参数化查询请求示例1:
- 数据类型支持
GES目前支持char、char_array、float、double、Boolean、long、Integer、date、enum、string共10种数据类型,布尔型和数值型在Cypher语法中都能得到支持,其他类型和Cypher存在如下的映射关系,在GES内部实现了类型的转换:
表10 GES和Cypher的类型映射关系 GES类型
Cypher类型
备注
char
String
-
char_array
String
-
string
String
-
enum
String
由于Cypher语法中未提供枚举相关的语法,在Cypher查询时enum作为String进行输出,使用Cypher设置属性时对于不在枚举列表中的值会设置失败。
说明:图规格为一千亿边的图暂不支持该参数。
date
Temporal
目前支持Date按GES的日期格式输入和输出,暂不支持调用Cypher日期函数输入日期。
表11 Cypher特殊类型支持情况 类型
支持情况
查询举例 & 备注
Node
支持
match (n) return n limit 10
Relationship
支持
match (n)-[r]->(m) return r limit 10
List
支持
return [1,2,3] as li
Map
支持
match (n)-->(m) return {start:id(n), end:id(m)}
Path
支持
match p=(n1)-[:friends*1..2]-(n2) return p limit 10
说明:图规格为一千亿边的图暂不支持该参数。
Point、Spatial
暂不支持
-
对表 Cypher特殊类型支持情况中提到的特殊类型,其中除了List用于匹配GES中的多值属性外,其他类型均无法通过set语句设为点边上某个属性的值。
- 表达式
Cypher查询支持多种的表达式,可以组合成丰富的过滤条件,目前支持的表达式如下:
运算类型
表达式
举例&备注
逻辑运算
and
match (n:user) where n.age='Under 18' and n.gender='F' return n
or
match(n:user) where n.`Zip-code`='22181' or n.userid=6 return n
not
match(n:movie) where not n.genres contains 'Drama' return n
空值判断
is null
match (n) where n.userid is null return n
is not null
match (n) where n.userid is not null return n
比较运算
>,>=,<,<=,=,<>
match(n:user) where n.userid>=5 return n
字符串比较
starts with
match(n:movie) where n.genres starts with 'Comedy' return n
ends with
match(n:movie) where n.genres ends with 'Drama' return n
contains
match(n:movie) where n.genres contains 'Drama' return n
List相关运算
in
match(n:student) where 'math' in n.courses return n
[]运算符
match(n:user) return n[' userid']
with [1, 2, 3, 4] as list return list[0]
with [1, 2, 3, 4] as list return list[0..1]
match p=(n)-->(m) return [x in nodes(p) where x.gender='F'|id(x)] (一千亿边暂不支持该条运算符)
Cypher查询的where子句暂不支持算数运算符、正则匹配等。
- 函数和过程
- 函数
在分组聚集、点边操作时,cypher支持一系列的函数,目前支持的函数如下所示:
- 聚集函数
- 普通函数
根据入参不同,普通函数分为点边操作类、路径操作类、列表操作类、值操作类等几类函数。
表12 点边操作类 函数名
释义
举例
id
获取点的id
match (n) return id(n)
labels
获取点的label
match (n) return labels(n)
type
获取边的label
match(n)-[r]->(m) return type(r)
degree(2.2.26)
获取点的度数
match (n) where id=’Vivian’ return degree(n)
inDegree(2.2.26)
获取点的入度
match (n) where id=’Vivian’ return inDegree(n)
outDegree(2.2.26)
获取点的出度
match (n) where id=’Vivian’ return outDegree(n)
表13 路径操作类函数(2.2.19) 函数名
释义
举例
nodes
获取路径上的点列表
match p=(n)-[:friends*1..2]->(m) return nodes(p)
图规格为一千亿边的图暂不支持该函数。
relationships
获取路径上的边列表
match p=(n)-[:friends*1..2]->(m) return relationships(p)
图规格为一千亿边的图暂不支持该函数。
length
获取路径长度
match p=(n)-[:friends*1..2]->(m) return length(p)
表14 列表操作类函数 函数名
释义
举例
head
获取列表的第一个元素
with [1,2,3,4] as list return head(list)
last
获取列表的最后一个元素
with [1,2,3,4] as list return last(list)
size
获取列表长度
with [1,2,3,4] as list return size(list)
表15 值操作类 函数名
释义
举例
toString(2.2.21)
将其他值类型转换为string
match (n) where toString(labels(n)) contains 'movi' return n
toUpper(2.2.26)
将字符串变为大写
match (n:movie) return toUpper(n.title)
toLower(2.2.26)
将字符串变为小写
match (n:movie) return toLower(n.title)
toInteger(2.2.29)
将字符串转为int类型
with '123' as p return toInteger(p)
toLong(2.2.29)
将字符串转为long类型
with '123' as p return toLong(p)
toFloat(2.2.29)
将字符串转为float类型
with '123.4' as p return toFloat(p)
toDouble(2.2.29)
将字符串转为double类型
with '123.4' as p return toDouble(p)
toBoolean(2.2.29)
将字符串转为bool类型
with 'true' as p return toBoolean(p)
size(2.2.29)
获取字符串的字符长度
with 'GES' as p return size(p)
表16 谓词函数(2.2.19) 函数名
释义
举例
all
全部元素满足表达式,则返回true
all (x in p where x>1)
any
任意一个元素满足表达式,则返回true
any (x in p where x>1)
none
全部元素无法满足表达式,返回true
none (x in p where x>1)
single
有且仅有1个元素满足表达式,返回true
single (x in p where x>1)
表17 算法表达式(2.3.2) 函数名
释义
举例
shortestPath
返回两点间最短路
给定点n,m 返回两点间最短路,方向为m到n,边label为rate:
with n,m, shortestPath((n)<-[:rate*]-(m)) as p return p
allShortestPaths
返回两点间全最短路集合
给定点n,m 返回两点间全最短路集合:
with n,m, allShortestPaths((n)-[*]-(m)) as p return p
- sum()、avg()、max()、min()等聚集函数在千亿规格暂不开放,sin()、cos()等数学函数后续将陆续开放。
- 点id的兼容性
- Cypher添加点时不提供设置id的语法,GES中添加点需要一个字符串型的id,来唯一的标识一个点。为了兼容Cypher语法,当前Create语句实现中,通过使用一个特殊的标识符_ID_指定点的id。例如create (n{_ID_:’123456’} )语句,会创建一个id为’123456’的点。
- 若创建时未指明id,则系统为此点生成一个随机id。
标识符“_ID_”仅在create语句中支持,match、set等子句均不支持_ID_标识。Match子句中可使用函数id()获取点id。
- 添加边时的平行边处理策略:
- 添加无label的边的方法:
通过Cypher添加边时必须指定label,所以指定待添加边的label为默认值”__DEFAULT__”即可,例如create ()-[r:__DEFAULT__]->() return r