关于 YMatrix
部署数据库
使用数据库
管理集群
最佳实践
高级功能
高级查询
联邦查询
Grafana 监控
备份恢复
灾难恢复
图数据库
管理手册
性能调优
故障诊断
工具指南
系统配置参数
SQL 参考
AGE 使用名为 agtype 的自定义数据类型,这是 AGE 返回的唯一数据类型。Agtype 是 JSON 的超集,也是 JsonB 的自定义实现。
在 Cypher 中,null 用于表示缺失或未定义的值。从概念上讲,null 意味着"一个缺失的未知值",它的处理方式与其他值有所不同。例如,从一个不具有某属性的顶点获取该属性会产生 null。大多数以 null 作为输入的表达式会产生 null。这包括在 WHERE 子句中用作谓词的布尔表达式。在这种情况下,任何不为 true 的值都被解释为 false。null 不等于 null。不知道两个值并不意味着它们是相同的值。因此表达式 null = null 产生 null 而不是 true。
输入/输出格式
查询
SELECT *
FROM cypher('graph_name', $$
RETURN NULL
$$) AS (null_result agtype);
null 将显示为空白。
结果:
null_result
-------------
(1 row)
Agtype 和 Postgres 中 NULL 的概念与 Cypher 中的相同。
integer 类型存储整数,即没有小数部分的数字。Integer 数据类型是一个 64 位字段,存储范围从 -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 的值。尝试存储超出此范围的值将导致错误。
integer 类型是常见的选择,因为它在范围、存储大小和性能之间提供了最佳平衡。smallint 类型通常仅在磁盘空间紧张时使用。bigint 类型设计用于 integer 类型范围不足的情况。
输入/输出格式
查询
SELECT *
FROM cypher('graph_name', $$
RETURN 1
$$) AS (int_result agtype);
结果:
int_result
------------
1
(1 row)
float 数据类型是一种不精确的、可变精度的数值类型,符合 IEEE-754 标准。
不精确意味着某些值无法精确转换为内部格式,而是以近似值存储,因此存储和检索值时可能会出现轻微差异。管理这些误差及其在计算中的传播是数学和计算机科学的一个完整分支的主题,此处不做讨论,但需注意以下几点:
过大或过小的值将导致错误。如果输入数字的精度过高,可能会进行舍入。太接近零而无法表示为与零不同的数字将导致下溢错误。
除了普通数值外,浮点类型还有几个特殊值:
这些分别表示 IEEE 754 的特殊值"正无穷"、"负无穷"和"非数字"。在 Cypher 命令中将这些值作为常量写入时,必须用引号括起来并进行类型转换,例如:
SET x.float_value = '-Infinity'::float
在输入时,这些字符串以不区分大小写的方式识别。
输入/输出格式:
要使用 float,请标注小数值。
查询
SELECT *
FROM cypher('graph_name', $$
RETURN 1.0
$$) AS (float_result agtype);
结果:
float_result
--------------
1.0
(1 row)
AGE 提供标准的 Cypher boolean 类型。boolean 类型可以有几种状态:true、false 和第三种状态 unknow,由 Agtype null 值表示。
布尔常量可以在 Cypher 查询中使用关键字 TRUE、FALSE 和 NULL 表示。
输入/输出格式
查询
SELECT *
FROM cypher('graph_name', $$
RETURN TRUE
$$) AS (boolean_result agtype);
与 Postgres 不同,AGE 的布尔值输出完整单词,即 true 和 false,而不是 t 和 f。
结果:
boolean_result
----------------
true
(1 row)
Agtype 字符串字面量可以包含以下转义序列:
| 转义序列 | 字符 |
|---|---|
| \t | 制表符 |
| \b | 退格 |
| \n | 换行 |
| \r | 回车 |
| \f | 换页 |
| ' | 单引号 |
| " | 双引号 |
| \ | 反斜杠 |
| \uXXXX | Unicode UTF-16 码点(\u 后必须跟 4 个十六进制数字) |
输入/输出格式
使用单引号 (') 标识字符串。输出将使用双引号 (")。
查询
SELECT *
FROM cypher('graph_name', $$
RETURN 'This is a string'
$$) AS (string_result agtype);
结果:
string_result
--------------------
"This is a string"
(1 row)
所有示例将使用 WITH 子句和 RETURN 子句。
通过使用方括号并用逗号分隔列表中的元素来创建字面量列表。
查询
SELECT *
FROM cypher('graph_name', $$
WITH [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] as lst
RETURN lst
$$) AS (lst agtype);
结果:
lst
------------------------------------
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
(1 row)
列表可以包含 null 值,与独立的 null 值不同,它会在列表中显示为单词 'null'。
查询
SELECT *
FROM cypher('graph_name', $$
WITH [null] as lst
RETURN lst
$$) AS (lst agtype);
结果:
lst
--------
[null]
(1 row)
要访问列表中的单个元素,再次使用方括号。这将从起始索引提取到但不包括结束索引。
查询
SELECT *
FROM cypher('graph_name', $$
WITH [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] as lst
RETURN lst[3]
$$) AS (element agtype);
结果:
element
---------
3
(1 row)
查询
SELECT *
FROM cypher('graph_name', $$
WITH [0, {key: 'key_value'}, 2, 3, 4, 5, 6, 7, 8, 9, 10] as lst
RETURN lst
$$) AS (map_value agtype);
结果:
map_value
-------------------------------------------------------
[0, {"key": "key_value"}, 2, 3, 4, 5, 6, 7, 8, 9, 10]
(1 row)
查询
SELECT *
FROM cypher('graph_name', $$
WITH [0, {key: 'key_value'}, 2, 3, 4, 5, 6, 7, 8, 9, 10] as lst
RETURN lst[1].key
$$) AS (map_value agtype);
结果:
map_value
-------------
"key_value"
(1 row)
也可以使用负数,从列表末尾开始访问。
查询
SELECT *
FROM cypher('graph_name', $$
WITH [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] as lst
RETURN lst[-3]
$$) AS (element agtype);
结果:
element
---------
8
(1 row)
可以在方括号内使用范围来返回列表的子集。
查询
SELECT *
FROM cypher('graph_name', $$
WITH [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] as lst
RETURN lst[0..3]
$$) AS (element agtype);
结果:
element
-----------
[0, 1, 2]
(1 row)
查询
SELECT *
FROM cypher('graph_name', $$
WITH [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] as lst
RETURN lst[0..-5]
$$) AS (lst agtype);
结果:
lst
--------------------
[0, 1, 2, 3, 4, 5]
(1 row)
查询
SELECT *
FROM cypher('graph_name', $$
WITH [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] as lst
RETURN lst[..4]
$$) AS (lst agtype);
结果:
lst
--------------
[0, 1, 2, 3]
(1 row)
查询
SELECT *
FROM cypher('graph_name', $$
WITH [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] as lst
RETURN lst[-5..]
$$) AS (lst agtype);
结果:
lst
------------------
[6, 7, 8, 9, 10]
(1 row)
查询
SELECT *
FROM cypher('graph_name', $$
WITH [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] as lst
RETURN lst[15]
$$) AS (element agtype);
结果:
element
---------
(1 row)
查询
SELECT *
FROM cypher('graph_name', $$
WITH [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] as lst
RETURN lst[5..15]
$$) AS (element agtype);
结果:
element
---------------------
[5, 6, 7, 8, 9, 10]
(1 row)
可以使用 Cypher 构建 Map。
可以使用简单的 agtype 构建一个简单的 map。
查询
SELECT *
FROM cypher('graph_name', $$
WITH {int_key: 1, float_key: 1.0, numeric_key: 1::numeric, bool_key: true, string_key: 'Value'} as m
RETURN m
$$) AS (m agtype);
结果:
m
------------------------------------------------------------------------------------------------------
{"int_key": 1, "bool_key": true, "float_key": 1.0, "string_key": "Value", "numeric_key": 1::numeric}
(1 row)
Map 也可以包含复合数据类型,即列表和其他 map。
查询
SELECT *
FROM cypher('graph_name', $$
WITH {listKey: [{inner: 'Map1'}, {inner: 'Map2'}], mapKey: {i: 0}} as m
RETURN m
$$) AS (m agtype);
结果:
m
-------------------------------------------------------------------------
{"mapKey": {"i": 0}, "listKey": [{"inner": "Map1"}, {"inner": "Map2"}]}
(1 row)
查询
SELECT *
FROM cypher('graph_name', $$
WITH {int_key: 1, float_key: 1.0, numeric_key: 1::numeric, bool_key: true, string_key: 'Value'} as m
RETURN m.int_key
$$) AS (int_key agtype);
结果:
int_key
---------
1
(1 row)
查询
SELECT *
FROM cypher('graph_name', $$
WITH {listKey: [{inner: 'Map1'}, {inner: 'Map2'}], mapKey: {i: 0}} as m
RETURN m.listKey[0]
$$) AS (m agtype);
结果:
m
-------------------
{"inner": "Map1"}
(1 row)
实体具有唯一的、可比较的标识,用于定义两个实体是否相等。
实体被分配一组属性,每个属性在集合中由其各自的属性键唯一标识。
简单实体被分配一个唯一的 graphid。graphid 是实体标签 id 和分配给每个标签的唯一序列的唯一组合。注意,比较来自不同图的实体时,id 可能会重叠。
GraphID 本质上是一个 64 位有符号整数 (int64)
64 位被分为两部分:
|<--- 16 bits --->|<----------- 48 bits ----------->|
| Label ID | Entry ID |
| (bits 63-48) | (bits 47-0) |
标签是将顶点和边分类到特定类别的标识符。
有关如何创建带标签的实体的信息,请参阅 CREATE 子句。
注意! 在 YMatrix AGE 中,将标签实现为 TABLE ,即一个 LABEL 于一个 TABLE 一一对应。
顶点和边都可以有属性。属性是属性值,每个属性名称应仅定义为字符串类型。
数据格式:
| 属性名称 | 描述 |
|---|---|
| Id | 此顶点的 graphid |
| label | 此顶点的标签名称 |
| properties | 与此顶点关联的属性 |
{id:1; label: 'label_name'; properties: {prop1: value1, prop2: value2}}::vertex
查询
SELECT *
FROM cypher('graph_name', $$
WITH {id: 0, label: "label_name", properties: {i: 0}}::vertex as v
RETURN v
$$) AS (v agtype);
结果:
v
------------------------------------------------------------------
{"id": 0, "label": "label_name", "properties": {"i": 0}}::vertex
(1 row)
Edge 是一个实体,编码两个节点之间的有向连接,即源节点和目标节点。出边是从源节点角度看的有向关系。入边是从目标节点角度看的有向关系。边被分配恰好一个边类型。
数据格式:
| 属性名称 | 描述 |
|---|---|
| id | 此边的 graphid |
| startid | 源节点的 graphid |
| endid | 目标节点的 graphid |
| label | 此边的标签名称 |
| properties | 与此边关联的属性 |
输出:
{id: 3; startid: 1; endid: 2; label: 'edge_label' properties{prop1: value1, prop2: value2}}::edge
查询
SELECT *
FROM cypher('graph_name', $$
WITH {id: 2, start_id: 0, end_id: 1, label: "label_name", properties: {i: 0}}::edge as e
RETURN e
$$) AS (e agtype);
结果:
e
--------------------------------------------------------------------------------------------
{"id": 2, "label": "label_name", "end_id": 1, "start_id": 0, "properties": {"i": 0}}::edge
(1 row)
Path 是一系列交替的顶点和边。Path 必须以顶点开始,并且至少有一条边。
查询
SELECT *
FROM cypher('graph_name', $$
WITH [{id: 0, label: "label_name_1", properties: {i: 0}}::vertex,
{id: 2, start_id: 0, end_id: 1, label: "edge_label", properties: {i: 0}}::edge,
{id: 1, label: "label_name_2", properties: {}}::vertex
]::path as p
RETURN p
$$) AS (p agtype);
结果:
p
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------
[{"id": 0, "label": "label_name_1", "properties": {"i": 0}}::vertex, {"id": 2, "label": "edge_label", "end_id": 1, "start_id": 0, "properties": {"i": 0}}::edge, {"id": 1, "label": "label_name_2", "properties": {}}::ve
rtex]::path
(1 row)