值类型的相等性、排序和比较

此页面解释了 Cypher® 如何比较和排序不同值类型,包括相等性和不等性规则。

值的相等性与比较

相等性 (=) 和不等性 (<>) 运算符允许比较不同值的相等性。

相同类型的值仅当它们完全相同时才相等(例如 3 = 3"x" <> "xy")。

映射仅当它们将完全相同的键映射到相等的值时才相等,而列表仅当它们包含相同序列的相等值时才相等(例如 [3, 4] = [1+2, 8/2])。

不同类型的值根据以下规则视为相等

  • PATH 值被视为节点和关系交替出现的列表,并与所有包含相同序列节点和关系的列表相等。

  • 使用 =<> 运算符测试任何值与 null 的比较结果始终为 null。这包括 null = nullnull <> null。要可靠地测试值是否为 null,请使用 v IS NULLv IS NOT NULL(后者等同于 NOT(v IS NULL))。

其他值类型组合无法相互比较。例如,节点、关系和字面量映射不能相互比较。比较不可比较的值将抛出错误。

值的排序和比较

ORDER BY 要求所有值都是可排序的。以下几点解释了在使用 <=<>=> 运算符时如何进行比较。

  • 数值通过数值顺序进行排序比较(例如 3 < 4true)。

  • 所有与 java.lang.Double.NaN 的可比性测试都评估为 false。例如,当 b 为 NaN 时,1 > b1 < b 都为 false

  • 字符串值通过字典顺序进行排序比较(例如 "x" < "xy")。

  • 布尔值进行排序比较时,false < true

  • 在比较值进行排序时,如果其中一个参数是 null,结果始终为 null

  • 空间值不能使用 <=<>=> 运算符进行比较。要在特定范围内比较空间值,请使用 point.withinBBox() 函数或 point() 函数。

值的层次结构

不同类型的值根据预定义的层次结构排序,从最小到最大,如下列表所示

null 排在所有其他值之后。
混合 Cypher 类型的排序规则
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
表 1. 结果

{name: "Alice"}

[1, 2, 3]

2024-02-10

"hello"

true

42

null

行数: 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]

有关 LISTMAP 值的更多信息,请参阅值和类型 → 构造类型

空间和时间值的排序

以下适用于空间类型的排序

  • POINT 值排在列表之后,时间类型之前。

  • 不同坐标参考系统 (CRS) 的 POINT 值按 CRS 代码(SRID 字段的值)排序。对于支持的 CRS 集合,以下升序适用:4326497973029157

  • 具有相同 CRS 的 POINT 值依次按每个坐标值排序;首先是 x,然后是 y,最后是 z

  • 请注意,此排序不同于空间索引返回的顺序,后者遵循空间填充曲线。

以下适用于时间类型的排序

  • 时间类型排在空间类型之后,字符串之前。

  • 时间值遵循时间顺序。例如,2023-01-012024-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 小时。

以下适用于时间类型的比较

  • 时间即时值(如 DATETIMEDATE)在类型相同时可以进行比较。较早的即时被认为小于较晚的即时。

  • 时间点相同但时区不同的即时不被视为相等。为确保一致的排序,Cypher 首先按它们的实际时间点排序。如果两个即时时间相同但时区不同,它们将按其 UTC 偏移量排序(从西到东,意味着负偏移量优先)。如果它们时间、偏移量相同但命名时区不同,则按时区名称字母顺序排序。

  • 持续时间值不能直接比较。由于一天、一月或一年的长度不同,Cypher 不对持续时间定义严格的排序。因此,比较两个持续时间(例如 duration1 < duration2)将始终返回 null