![精通Neo4j](https://wfqqreader-1252317822.image.myqcloud.com/cover/113/47216113/b_47216113.jpg)
3.2.7 模式
模式和模式匹配是Cypher非常核心的部分。要高效地使用Cypher必须深入理解模式。
使用模式可以描述你期望看到的数据的形状。例如,在MATCH语句中,当用模式描述一个形状的时候,Cypher将按照模式来获取相应的数据。
模式描述数据的形式类似于在白板上画出图的形状。通常用圆圈来表达节点,使用箭头来表达关系。
模式在MATCH、CREATE和MERGE等语句中都会出现,后续章节会详细描述。
3.2.7.1 节点模式
模式能表达的最简单的形状就是节点。节点使用一对圆括号表示,然后中间含一个名字。例如:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P120_87717.jpg?sign=1739285430-TaFb1TuhenSgHvOn0awdQOHHnFV04FCM-0-95891131f1cfcb39a2181704d09d3f7f)
这个模式描述了一个节点,其名称使用变量a表示。
3.2.7.2 关联节点的模式
模式可以描述多个节点及其之间的关系。Cypher使用箭头来表达两个节点之间的关系。例如:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P120_87725.jpg?sign=1739285430-qNLxRv8UqwUl4RYr9przJsrEdMNDMSRE-0-d10e6304d00eea7d4c5ae3c6307cea39)
这个模式描述了一个非常简单的数据形状,即两个节点和从其中一个节点到另外一个节点的关系。两个节点分别命名为a和b,关系是有方向的,从a指向b。
这种描述节点和关系的方式可以扩展到任意数量的节点和它们之间的关系,例如:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P120_87732.jpg?sign=1739285430-Y3Fgq8aTvmoSq61EkaRdBu0zcCLEHPe5-0-101faf2970ff9de9b0a47bf7d0a097dc)
这一系列相互关联的节点和关系被称为路径。
注意,节点的命名仅仅当后续的模式或者Cypher查询中需要引用时才需要。如果不需要引用,则命名可以省略。例如:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P120_87739.jpg?sign=1739285430-gDIGuvBzhvf6buMqshK74TL1Nw9x9Bsn-0-f70df26a9fc99f7f5e5bde50192859f7)
3.2.7.3 标签
模式除了可以描述节点之外,还可以用来描述标签。比如:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P120_87746.jpg?sign=1739285430-AhRtuqNZ4DLicTbl5Y00W5ZQB1VjaXXQ-0-4f55e56144a82c8af3357d5dbad298a4)
也可以描述一个节点的多个标签,如:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P120_87753.jpg?sign=1739285430-0egNaTvfnFG9gtuef58g0bbn4WS355gG-0-42d1490454726c75e24926550148c40c)
3.2.7.4 指定属性
节点和关系是图的基础结构。Neo4j的节点和关系都可以有属性,这样可以建立更丰富的模型。属性在模式中使用键值对的Map结构来表示,然后用大括号包起来。例如,一个有两个属性的节点如下所示:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P120_87760.jpg?sign=1739285430-itXoOHSIwTru6lCttpPeWc6rZA1BvsjK-0-b69866ee35356526ee652b2a5a11f253)
关系中的属性如下所示:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P120_87767.jpg?sign=1739285430-huwJMPU7lxZsbTzi2WtcUS4s7NjtnNi6-0-5e3cb8917cf5000a476e20afaaed4c80)
当模式中有属性时,它实际上为数据增加了额外的约束。在CREATE语句中,属性会被增加到新创建的节点和关系中。在MERGE语句中,属性将作为一个约束去匹配数据库中的数据是否存在该属性。如果没有匹配到,则这时MERGE的行为将与CREATE一样,即属性将被设置到新创建的节点和关系中。
提示:模式在CREATE语句中支持使用单个参数来指定属性。例如:CREATE (node$paramName)。但这在其他语句中是不行的,因为Cypher在编译查询的时候需要知道属性的名称,以便能够高效地匹配。
3.2.7.5 描述关系
如前面的例子所示,可以用箭头简单地描述两个节点之间的关系。它描述了关系的存在性和方向性。但如果不关心关系的方向,则箭头的头部可以省略。例如:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P121_87778.jpg?sign=1739285430-gGyAETSype2EFAuonkFXQ4N0MeLbKmvZ-0-bbfba77a3af6e7fca7870e77aca5153b)
与节点类似,如果后续需要引用到该关系,则可以给关系赋一个变量名。变量名需要用方括号括起来,放在箭头的短横线中间,如下所示:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P121_87785.jpg?sign=1739285430-rUAZhsOFtDhMrUaj4H5QAaOtGcwOCheD-0-b50532624c23f241db79fde44c50ed29)
就像节点有标签一样,关系可以有类型。可以通过如下方式给关系指定类型:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P121_87792.jpg?sign=1739285430-HvD5qI7yDwTsiDI2cRk22je7X8i8kpLu-0-3a2162e5bee992e903c64dc44523b773)
不像节点可以有多个标签,关系只能有一个类型。但如果所描述的关系可以是一个类型集中的任意一种类型,可以将这些类型都列入模式中,它们之间以竖线“|”分隔,例如:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P121_87799.jpg?sign=1739285430-4YlLAfu18u88xtnMnBHNMn4dV4gI1hF7-0-72d55342270801185ca05eb25a4fb0d8)
注意:这种模式仅适用于描述已经存在的数据(如在MATCH语句中),而在CREATE或者MERGE语句中是不允许的,因为一个关系不能创建多个类型。
与节点类似,关系的命名也是可以省略的,例如:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P121_87806.jpg?sign=1739285430-6oPngQPLYxrsLgWh0WmUptHscZojohij-0-76be8ce0e34a09c41fa90de0481410a6)
与使用一串节点和关系来描述一个长路径的模式不同,很多关系(以及中间的节点)可以采用指定关系的长度的模式来描述,例如:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P121_87813.jpg?sign=1739285430-2zAVvp5DAYcdWUB5shEGJmYZZbBOe17n-0-d1eb0b043e8300eb5102535f6826f23d)
它描述了一张有三个节点和两个关系的图。这些节点和关系都在同一条路径中(路径的长度为2)。它等同于:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P121_87820.jpg?sign=1739285430-eb5FCU7m8ML8ZijY04BskSZeD3eKvWsj-0-28e3647fb3f815a781d08c6d11b68c5e)
关系的长度也可以指定一个范围,这被称为可变长度的关系,例如:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P121_87827.jpg?sign=1739285430-8AlZZmn2tmVCp9pGJyKChOzFnfIZXreG-0-35c651fcc6b63275d23a09fb73b13ff6)
关系的长度最小值为3,最大值为5。它描述了一个或者有4个节点和3个关系,或者5个节点4个关系,或者6个节点和5个关系连在一起的图组成的一条路径。
长度的边界也是可以省略的,如描述一个路径长度大于等于3的路径:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P121_87834.jpg?sign=1739285430-FvO77ObzsUSkKfapfHvR8H5W2mLQ7GWY-0-26949fe6a1b1f72737a5ea5655b648b7)
路径长度小于等于5的路径,例如:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P121_87841.jpg?sign=1739285430-0kv16JRcEj2RDQMkbhnG4ZeIDY02nGT2-0-d392ca55bbf583e53bc8e83c69b71296)
两个边界都可以省略,这允许任意长度的路径,例如:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P122_87852.jpg?sign=1739285430-DhCROKNDOCEWzZjkKvvi084ciMBup1cp-0-a02fca33f81863afc01e3a1011e51248)
我们来看一个简单的查询例子:
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P122_102542.jpg?sign=1739285430-oszMKeN0YANXHg86MJPkjXTDPjOTRYFJ-0-37810fa15e0fd1e618d2442b08edc2d7)
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P122_102544.jpg?sign=1739285430-wtqTqh02pM36DRyPEPh9SpdMikk8iLs4-0-ec76f96b123a945c63c97b9a574d2bd9)
这个查询用于找到符合这个模式的数据:即指定一个节点(name属性值为Filipa)和与它关系为KNOWS的一步和两步的节点。这是一个查询一度和二度人脉的典型例子。
提示:可变长度的关系不能用于CREATE和MERGE语句。
3.2.7.6 赋值给路径变量
如上所述,连接在一起的一系列节点和关系称为路径。Cypher允许使用标识符给路径命名,例如:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P122_87878.jpg?sign=1739285430-XPEJImc8QZxoq5ftSj04svOCNKAe2VuH-0-06104f6e12d8b6e566de226c0e87f105)
在MATCH、CREAT和MERGE语句中可以这样做,但当模式作为表达式的时候不能这样做。