值类型的相等性、排序与比较
本页面解释了 Cypher® 如何比较和排列不同的值类型,包括相等和不等规则。
值的相等性与比较
相等 (=) 和不等 (<>) 运算符允许比较不同值的相等性。
相同类型的值只有在它们是完全相同的值时才相等(例如 3 = 3 和 "x" <> "xy")。
映射 (Maps) 只有在映射完全相同的键到相等的值时才相等;列表 (Lists) 只有在包含完全相同序列的相等值时才相等(例如 [3, 4] = [1+2, 8/2])。
不同类型的值根据以下规则被视为相等:
-
PATH值被视为节点和关系的交替列表,并且与所有包含节点和关系相同序列的列表相等。 -
使用
=或<>运算符测试任何值与null的关系,结果总是null。这包括null = null和null <> null。要可靠地测试一个值是否为null,请使用v IS NULL或v IS NOT NULL(后者等同于NOT(v IS NULL))。
其他值类型的组合彼此无法比较。例如,节点、关系和字面量映射之间无法比较。比较不可比较的值会抛出错误。
值的排序与比较
ORDER BY 要求所有值都是可排序的。以下几点解释了在使用 <=、<、>=、> 运算符时如何进行比较。
-
数值类型使用数值顺序进行排序比较(例如
3 < 4为true)。 -
所有与
java.lang.Double.NaN的可比性测试结果均为false。例如,当b为 NaN 时,1 > b和1 < b均为false。 -
字符串值使用字典顺序进行排序比较(例如
"x" < "xy")。 -
布尔值按照
false < true的顺序进行排序。 -
当比较排序值时,如果其中一个参数为
null,则结果总是null。 -
空间值和
VECTOR值不能使用<=、<、>=、>运算符进行比较。若要在特定范围内比较空间值,请使用point.withinBBox()或point()函数。
有关 VECTOR 类型的排序,请参阅 排序 VECTOR 类型。
值层级
不同类型的值根据预定义的层级进行排序,从最小到最大,具体列表如下:
null 排在所有其他值之后。 |
WITH [42, "hello", null, true, {name: "Alice"}, [1, 2, 3], date("2024-02-10")] AS v
UNWIND v AS values
RETURN values
ORDER BY values
| 值 (values) |
|---|
|
|
|
|
|
|
|
行:7 |
排序列表和映射值
列表按字典顺序进行比较。
-
元素从列表开头到结尾逐对比较。顺序由第一个元素不同的对定义。例如,
[1, 'foo', 3]小于[1, 2, 'bar'],因为'foo'小于2。 -
如果一个列表较短,则会用空元素填充,空元素被认为小于任何其他值(包括
null)。例如,[1, 'foo']小于[1, 'foo', 3],且[1]小于[1, null]。
映射按大小、键和值排序。
-
映射首先按大小比较:条目最少的映射最小。例如,
{a: 1}小于{a: 0, b: 'foo'}。 -
相同大小的映射按键的字母顺序进行比较。例如,
{b: 100, a: 'foo'}小于{a: '', c: null},因为['a', 'b']小于['a', 'c']。 -
对于具有相同键集的映射,比较基于值。按字母顺序对键排序后,逐对比较值。例如,
{b: 100, a: 'foo'}小于{a: 'foo', b: null},因为['foo', 100]小于['foo', null]。
有关 LIST 和 MAP 值的更多信息,请参阅 值与类型 → 构造类型。
排序空间和时序值
以下内容适用于 空间类型 的排序:
-
POINT值排在列表之后,时序类型之前。 -
具有不同坐标参考系统 (CRS) 的
POINT值按 CRS 代码(SRID 字段的值)排序。对于支持的 CRS 集合,适用以下升序:4326,4979,7302,9157。 -
具有相同 CRS 的
POINT值依次按每个坐标值排序;首先是x,然后是y,最后是z。 -
请注意,此排序顺序与空间索引返回的顺序不同,后者遵循空间填充曲线。
以下内容适用于 时序类型 的排序:
-
时序类型排在空间类型之后,但字符串之前。
-
时序值遵循时间先后顺序。例如,
2023-01-01位于2024-01-01之前。 -
时序值首先按类型排序,然后按值排序。例如,
DATETIME被认为比DATE“大”,而2023-02-10T12:00:00位于2023-02-10T15:00:00之前,因为在时间上更早。 -
由于无法完美比较持续时间 (Duration) 值(因为月和年的长度不同),Cypher 在
ORDER BY中定义了特定的排序规则:-
1 年被视为 365.2425 天(考虑闰年)。
-
1 月被视为 30.436875 天(即 1/12 年)。
-
1 天始终为 24 小时。
-
以下内容适用于时序类型的比较:
-
时序瞬间值 (Temporal instant values)(如
DATETIME和DATE)在类型相同时可以比较。较早的瞬间被视为小于较晚的瞬间。 -
在同一时间点但处于不同时区的瞬间不被视为相等。为了确保一致的排序,Cypher 首先按其实际时间点排序。如果两个瞬间时间相同但时区不同,它们按 UTC 偏移量排序(从西到东,意味着负偏移量在前)。如果它们的时间和偏移量相同但命名的时区不同,则按时区名称按字母顺序排序。
-
持续时间值不能直接比较。由于天、月或年的长度不固定,Cypher 未为持续时间定义严格的排序。因此,比较两个持续时间(例如
duration1 < duration2)总是返回null。
排序向量类型
VECTOR 超类型按以下升序排列:
-
VECTOR -
VECTOR<TYPE> -
VECTOR(DIMENSION)
同时定义了坐标类型和维度的 VECTOR 类型,根据向量坐标类型的顺序进行升序排列,如下所示:
-
INTEGER8 -
INTEGER16 -
INTEGER32 -
INTEGER64 -
FLOAT32 -
FLOAT64
在同一坐标类型内,VECTOR 类型按维度排序,值较小的在前。相同坐标类型和维度的 VECTOR 类型按值逐对排序。
| A | B | 排序方式 | 原因 |
|---|---|---|---|
|
|
A < B |
坐标类型相同:按维度升序比较。 |
|
|
A < B |
坐标类型顺序: |
|
|
A < B |
定义了坐标类型但无维度 < 定义了维度但无坐标类型 |
|
|
A < B |
坐标类型顺序: |
|
|
B < A |
坐标类型顺序: |
|
|
A < B |
坐标类型和维度相同,按值逐对比较。 |
|
|
A < B |
|