![精通Neo4j](https://wfqqreader-1252317822.image.myqcloud.com/cover/113/47216113/b_47216113.jpg)
3.3.1 MATCH语句
MATCH语句用于指定的模式检索数据库。
3.3.1.1 简介
MATCH语句通过模式来检索数据库。它常与带有约束或者断言的WHERE语句一起使用,这使得匹配的模式更具体。断言是模式描述的一部分,不能看作是匹配结果的过滤器。这意味着WHERE应当总是与MATCH语句放在一起使用。
MATCH可以出现在查询的开始或者末尾,也可能位于WITH之后。如果它在语句开头,此时不会绑定任何数据。Neo4j将设计一个搜索去找到匹配这个语句以及WHERE中指定断言的结果。这将牵涉数据库的扫描,搜索特定标签的节点或者搜索一个索引以找到匹配模式的开始点。这个搜索找到的节点和关系可作为一个“绑定模式元素(Bound Pattern Elements)”。它可以用于匹配一些子图的模式,也可以用于任何进一步的MATCH语句,Neo4j将使用这些已知的元素来找到更进一步的未知元素。
Cypher是声明式的,因此查询本身不指定搜索的算法。Neo4j会自动地用最好的方法去找到开始节点和匹配模式。WHERE中的断言可以在模式匹配之前、匹配中或者匹配后进行处理。这可以通过查询编译器来影响这个决定。详情可参见3.5.1节和3.6.4节。
MATCH语句示例如图3-3所示。
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P130_88408.jpg?sign=1739512080-x0aKIpDgudWQBGSSdwe60iRzxKUqgXgj-0-7a86508f4e5052ff7bb52d183381304e)
图3-3 MATCH语句示例
3.3.1.2 查找节点
1.查询所有节点
通过指定一个不带标签的节点的模式,可以返回图中的所有节点。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P130_102564.jpg?sign=1739512080-9ewIlMNBFtg2aw73ymEr02vVBfvkHmFp-0-49ec351ea97a5f7c32fa3646ea956678)
结果将返回数据库中的所有节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P130_102566.jpg?sign=1739512080-9n98IwW3dnoSn6lYRUMhU4ptVufTdgT6-0-29157762b4bf2de37b0e233259c1e0fd)
2.查询带有某个标签的所有节点
通过指定带有一个标签的节点的模式,可以获取满足该标签的所有节点。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P130_102565.jpg?sign=1739512080-Pil4EcIx84wVoy9gxmrf4eUt35egAGYV-0-cddabaecb4733b7320550fbfed050af0)
结果将返回数据库中的所有电影。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P130_101511.jpg?sign=1739512080-IX3shh5BaEXbzrgmRFUeGxbk8c3A687h-0-4d92666a6ba750ece8736ea9077763b1)
3.查询关联节点
符号--意为相关的,这个关系不带有类型和方向。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P131_102567.jpg?sign=1739512080-YoJtB2AK0DitudfHz7BwoguwdU2Cqyan-0-1d1acdc8f44c7ea68873daee05dbc642)
结果将返回'Oliver Stone'导演的所有电影。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P131_102567a.jpg?sign=1739512080-DtXC4JKUQoslTTZgYuEkhFU1WT4msvpE-0-bfeab1a00a3ee3ed18695725a4c1d0d6)
4.匹配标签
可以为查询的节点增加标签约束。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P131_102568.jpg?sign=1739512080-wc28uih2vlgdEXwiHiPNtmDXNTcaMI2q-0-92f43d33422e9a14c3b4ef4acd59e9f4)
结果将返回与Person 'Oliver Stone'相连的带有Movie标签的所有节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P131_102567b.jpg?sign=1739512080-2WfytwNO5GcrkfFeZE2Y8es3zEOHbQ41-0-b4e25894365437bcf7edca6c33d745d0)
3.3.1.3 查找关系
1.外向关系
关系的方向可以通过-->或者<--来表示。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P131_102569.jpg?sign=1739512080-jHXpsWicmFhHLE6ByRb9jaZ3VDwpWT2e-0-85cd8278149851579a7a39c7f4fae4ad)
结果将返回与Person 'Oliver Stone'外向连接的所有节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P131_101520.jpg?sign=1739512080-vPCZyVW68rjeqQdMoGkdhBM4p7zQjUTJ-0-24e5a0c2927360f663e891e77cf0981b)
2.有向关系和变量
当需要过滤关系中的属性,或者返回关系的时候,就很有必要使用变量了。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P132_102570.jpg?sign=1739512080-ExcsI3JvcfDeX2r5JLZq2ivKgLmlkIKc-0-84f3f79482dd90146f6a92d9acd0e0d6)
结果将返回'Oliver Stone'的外向关系的类型。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P132_101522.jpg?sign=1739512080-n4EKSGxXXTJqI1ohuL8ciBHdvJfth5aG-0-381fa91776e9f62ccfb919181b47a0eb)
3.匹配关系类型
当已知要匹配关系的类型时,可通过冒号后面紧跟关系类型。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P132_102571.jpg?sign=1739512080-4oUXcvQkQmnrdYsSJkxXjG50SK9VWPS5-0-5a962e47e82d9e77cafca67ce8d5bf9c)
结果将返回电影'Wall Street'中的所有演员。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P132_101525.jpg?sign=1739512080-oMrDJkt3wIbBrFDmzsEidUE5cCoxpjvZ-0-e32cac8b81cfd2e9022f9741cbbfe3fd)
4.匹配多种关系类型
当需要匹配多种关系中的一种时,可以通过竖线(|)将多个关系连接在一起。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P132_102572.jpg?sign=1739512080-QXpSdoOqv6zCA0DKwXdlSBtOQUVfpHQb-0-009c02aa0ef18afc17499d85aca42b91)
结果将返回与'Wall Street'节点关系为ACTED_IN或者DIRECTED的所有节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P132_101528.jpg?sign=1739512080-R69uez2qcGwGYRQPtHpZBz4vtUQFQSKa-0-8c64f9392c6ce57abe8c53ce338575ad)
5.匹配关系类型和使用关系变量
如果想通过变量来引用关系和指定关系类型,可以将它们放在一起。例如:
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P132_102573.jpg?sign=1739512080-f10iTcdwzN7cq4ynDWScmVh3Zyy8P8TH-0-7077f9cb0441bf8debeaaa8d20afc6a4)
结果将返回电影'Wall Street'中所有演员的角色。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P133_101531.jpg?sign=1739512080-FRaFaraOr2QQNGJDgQ3MdM1r22baDT5I-0-8ba4b9eccb8fd8990f5884ed70dcbb7d)
3.3.1.4 关系的深度
1.带有特殊字符的关系类型
某些时候数据库中可能会有非字母字符的类型,或者中间含有空格。可以使用反引号“`”将它们括起来。下面的例子在'Charlie Sheen'和'Rob Reiner'之间添加了一个包含有空格的关系。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P133_102574.jpg?sign=1739512080-6diYjef9L5k3vCMwOUAgSzQ4tWyMKKLE-0-88c918c0c8333299e8d9c93d6ee69ac9)
该查询产生的结果如图3-4所示。
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P133_88573.jpg?sign=1739512080-tXfjTiO3NdLHTfpeeobN99LM84scbvCm-0-128bdd31baf9bce3ce4ed208e7c29304)
图3-4 查询结果图
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P133_102575.jpg?sign=1739512080-MLnNf0Hnpn29zE8SomiRRzCtx8sZqrYc-0-a3fd2b01fa32b5eca2613be12f63a90b)
结果将返回带有空格的关系类型。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P133_101534.jpg?sign=1739512080-iTxNjqp7zC1g5K3cc2cJCYBqWEJE7vwl-0-2f578f45d1ddde34f47cce8b5441f1d5)
2.多个关系
关系可以多语句以()--()的形式来表达,或者它们相互连接在一起。例如:
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P133_102576.jpg?sign=1739512080-rjXHz2FTj8F9HYnsT38XDrXZldh8ZkhU-0-6ffe9192718bba61fa4e289315972232)
结果将返回'Charlie Sheen'参演的电影和电影的导演。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P134_101537.jpg?sign=1739512080-g7PrSwsrnt7NKOMeB3Yiz0C6phpRTTCc-0-93d23435b6fe7a18bf8bc39687d93aed)
3.可变长度关系
可变长度关系和节点的语法如下:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P134_88621.jpg?sign=1739512080-TclPwvbQHAumiLoAwaxBtdC93Pz6291P-0-04621ec536145b4e7b986f55b758583f)
minHops和maxHops都是可选的,默认值分别为1和无穷大。当没有边界值的时候,点也是可以省略的。当只设置了一个边界的时候,如果省略了点,则意味着这是一个固定长度的模式。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P134_102577.jpg?sign=1739512080-8RbulfQYKlWBuDdl9aTbQQsgVTOx53Ze-0-7860730764300980bcf47c4794be7b99)
结果将返回与'Charlie Sheen'具有1跳(Hop)到3跳关系的所有电影。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P134_88621a.jpg?sign=1739512080-2yOJXaUzMyI3VJI0hSJnDmqiuFziGDgO-0-38b3816b10006394c34de9b88da71b95)
4.具有多种关系类型的可变长度关系
可变长度关系可以与多种关系类型组合。在这种情况下,*minHops..maxHops适用于所有关系类型以及它们的任何组合。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P134_102578.jpg?sign=1739512080-zu4SvlPS7l8fNmum9j1QpLDmsUJVfZlN-0-ea08f38c523025075dd767dc268f90cb)
结果将返回与'Charlie Sheen'具有2跳ACTED_IN或DIRECTED关系的所有人员。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P134_101543.jpg?sign=1739512080-5hxEDS5m8NroYO23j148ix2Fx9fMtbSe-0-7e794d4f5c5ce5f88db75475e43aa796)
5.可变长度关系的关系变量
当连接两个节点之间的长度是可变的,那么关系变量返回的将可能是一个关系列表。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P135_102581.jpg?sign=1739512080-N0mvl7vsCFKF7OYnse8tTtqJ0Lre60Uk-0-9b43e289ea5cbfeea062bc48267b829d)
结果将返回一个关系列表。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P135_101545.jpg?sign=1739512080-5nDkdOOkb89LG32yY8qSVSK7CjYOty3U-0-01b039a21761027e92a1aeb58a8a3f59)
6.可变长度路径上的属性匹配
带有属性的可变长度关系,意味着路径上的所有关系都必须包含给定的属性值。在这个查询中,'Charlie Sheen'和他的父亲'Martin Sheen'之间有两条路径。其中一条包含一个'blocked'关系,另外一条则没有。首先,通过下面的语句增加BLOCKED和UNBLOCKED关系。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P135_102582.jpg?sign=1739512080-M0GFUgfkt9bS0y7RPfC8g48eAGqhiTN6-0-61eafed64859988abf8a0c6d58f620b3)
后续将以图3-5为基础来讲解。
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P135_88710.jpg?sign=1739512080-bT5EszhYLtMBEvV58qQ8MmYUmG68VZmx-0-4b611867c8b864c3c8fdb8f6a1fa69df)
图3-5 可变长度路径上的属性匹配图例
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P135_102583.jpg?sign=1739512080-Z0nCVNwSEC1VtjJKY7tON5lMdM0SNA7H-0-cf356ef020bcc6e611e3e046611aed83)
结果将返回'Charlie Sheen'和'Martin Sheen'之间满足blocked属性值为false的所有关系。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P135_101548.jpg?sign=1739512080-HyrafedAmfqRXb8S3z6ESzRMX60WkUTQ-0-8808777233303ed477c8cefead87bc3a)
7.零长度路径
可以通过指定可变长度路径的下界值为零,来实现两个变量指向同一个节点。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P136_102584.jpg?sign=1739512080-AaxGIZlsdkDJ6DEJSOttztzdGBlyafMl-0-252ae6d318ada3688927074615004727)
结果将返回电影本身及一跳关系的演员和导演。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P136_101551.jpg?sign=1739512080-o4oJHseP3AOYFEwL8DWXNFqqM3MnjXcP-0-bd8ffa2a79bf1eb3b52cb7c17a425a1a)
8.命名路径
如果想返回或者需要对路径进行过滤,可以将路径赋值给一个变量。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P136_102585.jpg?sign=1739512080-Bsf47tiGcafYDA2Q82sjR38a2i2K80Wa-0-e2e42af249d90680b517778a41ae9007)
结果将返回从'Michael Douglas'开始的路径。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P136_101554.jpg?sign=1739512080-cM8f0cefzOqBThmWihuBXRE4oMEbjctn-0-ffba70e42d1c89cbca292e81e7b6bcf3)
9.不指定方向匹配关系
可以不指定方向来匹配关系,Cypher将尝试匹配两个方向的关系。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P136_102586.jpg?sign=1739512080-wuntGgE9ZhQhz7ttJ7bz2xzjoQrMXrDI-0-812ee96c0a38521b9553a0103c7043cc)
结果将返回两个相连的节点a和b。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P136_101557.jpg?sign=1739512080-KA5XUXBB6Ygb2y90JSvgPn8ycDqmFcgN-0-5d950cc095857fc47d1dcf284e881bcb)
3.3.1.5 最短路径
1.单条最短路径
通过使用shortestPath函数很容易找到两个节点之间的最短路径,如下所示。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P137_102587.jpg?sign=1739512080-AEUtKSEQzhnJkYNT28LdWh8EGhSAJBwl-0-66f8a00df088fef53861e23588debaae)
上面查询的含义为:找到两个节点之间的最短路径,路径最大长度为15。在搜索最短路径的时候,还可以使用关系类型、最大跳数和方向等约束条件。如果用到了WHERE语句,则相关的断言会被包含到shortestPath中去。如果路径的关系元素中用到了none()或者all()断言,那么这些将用于在检索时提高性能。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P137_101560.jpg?sign=1739512080-8NzujUy5uNBIS9bYzq97hxAq7pqyE0ce-0-7a38261a721ab42ac5f1238082dcc6ce)
2.带断言的最短路径
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P137_102588.jpg?sign=1739512080-7vQ5RsiWG1VSNGFH3DblxtwVPCkQE0FS-0-34794b2ff1ba52420e9f43c877a0ff8c)
这个查询寻找'Charlie Sheen'和'Martin Sheen'之间的最短路径,通过WHERE断言可以确保不考虑两个节点之间的父亲/儿子关系。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P137_101562.jpg?sign=1739512080-FXrVlWA5sm5M29V5AmUHDPzgM7DIxbuk-0-f331c4975d606fe80070465d2d1698fd)
3.所有最短路径
找到两个节点之间的所有最短路径。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P137_102589.jpg?sign=1739512080-4bABytHn3fDWsz9Ui2pmVw1Gjeubwhoi-0-f6242c88cbac7503421611bc4a66337f)
结果将找到'Martin Sheen'和'Michael Douglas'之间的两条最短路径。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P138_88867.jpg?sign=1739512080-7NnMs4u31perEOU4LtyRlCl5ahwHT4ZM-0-d08504d8a10dc98677d1336e77df5c95)
3.3.1.6 通过id查询节点或关系
1.通过id查询节点
可以在断言中使用id()函数来根据id查询节点。
提示:Neo4j会重用已删除的节点和关系的内部id。这意味着依赖Neo4j内部的id存在风险。因此,建议通过程序来产生id。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P138_102591.jpg?sign=1739512080-UfJmbOelNtMYqKDOixdQID1PUrUboIOr-0-8b830c2c11a15e497b0a336af9b4b6a6)
结果将返回节点id为0的节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P138_101566.jpg?sign=1739512080-utN5aQfTM1nsu6evMqemcS9oARKIBsNA-0-adc8bd55588827ebadc9292f217696a1)
2.通过id查询关系
通过id查询关系与查询节点类似,但在实践中不推荐这么做。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P138_102592.jpg?sign=1739512080-3e6O8WTuDtqMZ8HM4cJEudWIc7NIlODk-0-6bfdb77f624a2e2885537f6b6aa3c291)
结果将返回关系id为0的关系。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P138_101569.jpg?sign=1739512080-LCT4tlRF9zSagA40Pj18RlxkIwLkqksh-0-f978add6f37b10ef545e4ec0adb8fd66)
3.通过id查询多个节点
通过id查询多个节点的时候,可以将id放到IN语句中。
查询:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P138_102593.jpg?sign=1739512080-7JL6Oj2XqCNVqREcAsiIypOl1YL6acA3-0-a6f79ca4edcc74b569b38e05ae9c7767)
结果将返回IN语句中列出的所有节点。
结果:
![](https://epubservercos.yuewen.com/84FE89/26581284601284906/epubprivate/OEBPS/Images/Figure-P139_101572.jpg?sign=1739512080-vJ97iAVUKDVii6hB285zORhqST4Ft8hC-0-321d53bf530e2be7f1118c0138130e46)