值类型的相等性、排序和比较
此页面解释了 Cypher® 如何比较和排序不同值类型,包括相等性和不等性规则。
值的相等性与比较
相等性 (=
) 和不等性 (<>
) 运算符允许比较不同值的相等性。
相同类型的值仅当它们完全相同时才相等(例如 3 = 3
和 "x" <> "xy"
)。
映射仅当它们将完全相同的键映射到相等的值时才相等,而列表仅当它们包含相同序列的相等值时才相等(例如 [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
。 -
空间值不能使用
<=
、<
、>=
、>
运算符进行比较。要在特定范围内比较空间值,请使用point.withinBBox()
函数或point()
函数。
值的层次结构
不同类型的值根据预定义的层次结构排序,从最小到最大,如下列表所示
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
值 |
---|
|
|
|
|
|
|
|
行数: 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
之前,因为它在时间上更早。 -
由于没有完美的方法来比较持续时间值(因为月份和年份的长度不同),Cypher 为其在
ORDER BY
中的排序定义了一条特定规则-
1 年被视为 365.2425 天(已考虑闰年)。
-
1 个月被视为 30.436875 天(即 1/12 年)。
-
1 天始终为 24 小时。
-
以下适用于时间类型的比较
-
时间即时值(如
DATETIME
和DATE
)在类型相同时可以进行比较。较早的即时被认为小于较晚的即时。 -
时间点相同但时区不同的即时不被视为相等。为确保一致的排序,Cypher 首先按它们的实际时间点排序。如果两个即时时间相同但时区不同,它们将按其 UTC 偏移量排序(从西到东,意味着负偏移量优先)。如果它们时间、偏移量相同但命名时区不同,则按时区名称字母顺序排序。
-
持续时间值不能直接比较。由于一天、一月或一年的长度不同,Cypher 不对持续时间定义严格的排序。因此,比较两个持续时间(例如
duration1 < duration2
)将始终返回null
。