最近更新时间:2025-11-11 16:29:40
AGE 在原始数据类型(布尔值、字符串、整数和浮点数)及映射(Map)类型上,均提供了明确且一致的相等性(Equality)语义。此外,Cypher 在每种类型内部——尤其是整数、浮点数与字符串类型——也定义了良好的可比性(Comparability)与可排序性(Orderability)规则。
然而,在 不同类型数据值之间的比较 上,AGE 的行为与 PostgreSQL 的逻辑及 openCypher 规范略有不同:
定义了不同类型值之间的可比性。当它作为谓词评估的一部分(在 WHERE 中)发生时,这种偏离特别明显。
如果传递给 ORDER BY 的值具有不同类型,ORDER BY 不会失败。
底层概念模型复杂且有时不一致。这导致比较操作符、相等性、分组和 ORDER BY 之间的关系不明确:
可比性和可排序性彼此一致地对齐,因为所有类型都可以排序和比较。
在 AGE 中,由 IN、=、DISTINCT 和分组暴露的相等性和等价性之间的差异仅限于测试两个 null 值实例
在相等性中,null = null 是 null。
在等价性中,由 DISTINCT 和分组值时使用,两个 null 值总是被视为相同的值。
但是,如果 null 值是列表的元素或映射值,相等性会以不同方式处理 null 值。
openCypher 规范具有四个与相等性和排序相关的不同概念:
可比性由不等式操作符(>、<、>=、<=)使用,定义了两个值之间如何进行比较的基本语义。
换言之,可比性决定了表达式 a > b 或 a <= b 是否具有逻辑意义,以及如何评估比较结果。
相等性由相等操作符(=、<>)以及列表成员操作符(IN)使用,用于定义在这些上下文中两个值是否相同的判断逻辑。
例如,以下模式语法:
MATCH (p:Person {name: 'Alice'})实际上是相当于执行以下相等判断的简写:
MATCH (p:Person)
WHERE p.name = 'Alice'可排序性由 ORDER BY 子句使用,定义了值在结果集中如何排序的基础语义。
等价性由 DISTINCT 修饰符和投影子句(WITH、RETURN)中的分组使用,并定义在这些上下文中确定两个值是否相同的基础语义。
比较运算符在 Cypher 中承担两类核心职责:
相等性与可比性(Equality & Comparability) — 确保比较逻辑符合直觉与语义;
等价性与可排序性(Equivalency & Orderability) — 允许对结果集进行排序与分组。
在实际实现中,无法同时为这两类语义提供完全独立的比较逻辑。因此,AGE 优先保证等价性与可排序性,以确保在 ORDER BY、DISTINCT、GROUP BY 等语句中能够正确执行排序与分组操作。
可比性定义了 任意两种值 在执行不等式运算符(>、<、>=、<=)时的比较规则。不同数据类型的比较逻辑如下所述:
数字
不同类型的数字(不包括 NaN 值和无穷大)相互比较,就好像两个数字在数值上按升序相互比较之前都被强制转换为任意精度大十进制(目前在 Cypher 类型系统之外)。
与任何非数字值的比较遵循可排序性规则。
浮点数没有表示 agtype 整数和 agtype 数值范围内所有整数所需的精度。将整数或数值 agtype 转换为浮点数时,在高低范围内转换值时可能会发生意外结果
整数
整数按数值升序比较。
浮点数
浮点数(不包括 NaN 值和无穷大)按数值升序比较。
正无穷大是 FLOAT 类型,等于自身且大于任何其他数字,除了 NaN 值。
负无穷大是 FLOAT 类型,等于自身且小于任何其他数字。
NaN 值相互可比且大于任何其他浮点值。
数值
数值按数值升序比较。
布尔值
布尔值比较使得 false 小于 true。
与任何非布尔值的比较遵循可排序性规则。
字符串
字符串按字典顺序比较,即字符从字符串开始到结尾按升序成对比较。较短字符串中缺失的字符被认为小于任何其他字符。例如,'a' < 'aa'。
与任何非字符串值的比较遵循可排序性规则。
列表
列表按顺序比较,即列表元素从列表开始到结尾按升序成对比较。较短列表中缺失的元素被认为小于任何其他值(包括 null 值)。例如,[1] < [1, 0] 但也有 [1] < [1, null]。
与任何非列表值的比较遵循可排序性规则。
映射
映射的比较顺序未指定,留给实现。
映射的比较顺序必须与下面概述的相等性语义对齐。因此,任何包含将其键映射到 null 值的条目的映射都是不可比较的。例如,{a: 1} <= {a: 1, b: null} 评估为 null。
与任何非常规映射值的比较遵循可排序性规则。
实体
顶点
顶点的比较顺序基于分配的 graphid。
边
边的比较顺序基于分配的 graphid。
路径
路径的比较就好像它们是从起始节点到结束节点的路径的交替节点和关系的列表。例如,给定节点 n1、n2、n3 和关系 r1 和 r2,并且给定 n1 < n2 < n3 和 r1 < r2,那么通过 r1 从 n1 到 n3 的路径 p1 将小于通过 r2 从 n2 到 n1 的路径 p2。
用列表表示:p1 < p2<=> \[n1, r1, n3\] < \[n1, r2, n2\]<=> n1 < n1 || (n1 = n1 && \[r1, n3\] < \[r2, n2\])<=> false || (true && \[r1, n3\] < \[r2, n2\])<=> \[r1, n3\] < \[r2, n2\]<=> r1 < r2 || (r1 = r2 && n3 < n2)<=> true || (false && false)<=> true
与任何非路径值的比较将返回 false。
NULL
null 与任何其他值(包括其他 null 值)不可比较。
当使用 <、<=、>、>= 从最小值到最大值时,不同 agtype 的排序是:
Path
Edge
Vertex
Object
Array
String
Bool
Numeric, Integer, Float
NULL
纯净模式
