更新时间:2022-02-22 GMT+08:00

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为一个语句组,包含一到多条语句。其中每个元素的格式如表 statement参数说明

    表3 statement参数说明

    参数

    是否必选

    类型

    说明

    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。

响应

  • 要素说明
    表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: 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": []
    }
    1. 需要同时添加两个索引(点label索引和边label索引)才能正常使用Cypher查询。
    2. 不需要构建的情况:如果图中已经存在hasLabel为true, indexProperty为空的点索引或边索引,则不需要重复构建。
    3. 添加索引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仅在百亿以下规格图中支持(不包含百亿)。

    1. 目前暂不支持merge、foreach、optional等操作,暂不支持使用Cypher语句增删索引,后续会逐渐开放支持。
    2. 由于GES的元数据不是Schema Free的,点边label属性等有严格的限制,因此不支持Remove操作。
    3. 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
  • 数据类型支持

    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查询的where子句支持多种的表达式,可以组合成丰富的过滤条件,目前支持的表达式如下:

    运算类型

    表达式

    举例&备注

    逻辑运算

    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子句暂不支持case表达式、算数运算符、正则匹配等。

  • 函数和过程
    • 函数

    在分组聚集、点边操作时,cypher支持一系列的函数,目前支持的函数如下所示:

    1. 聚集函数
      目前支持count、collect两个聚集函数。

      函数名

      释义

      举例

      count

      求结果总数

      match (n) return count(*)

      match (n) return count(n.userid)

      collect(2.2.17)

      将结果聚集为列表

      match (n:movie) return n.genres, collect(n) as movieList

    2. 普通函数

      根据入参不同,普通函数分为点边操作类、路径操作类、列表操作类、值操作类等几类函数。

      表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)

      表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)

      • avg()、max()、min()等聚集函数,以及sin()、cos()等数学函数将在后续版本中陆续开放。
      • 过程

        目前GES 支持如下过程(Procedure):

        名称

        语句

        获取图模式相关信息

        call db.schema()

        获取点label

        call db.labels()

        获取边label

        call db.relationshipTypes()

        查询当前正在执行的Cypher语句

        call dbms.listQueries()

        根据queryId终止某条Cypher语句

        call dbms.killQuery('queryId')

        函数和过程名大小写敏感,须按小驼峰写法调用。

  • 点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。

  • 添加边时的平行边处理策略:

    通过cypher添加边的时候,允许添加重复边,此处的重复边的定义为<源点,终点>相同的两条边。

  • 添加无label的边的方法:

    通过Cypher添加边时必须指定label,所以指定待添加边的label为默认值”__DEFAULT__”即可,例如create ()-[r:__DEFAULT__]->() return r