提取路径时使用 `WITH` 或 `MATCH` 子句
Using `WITH` or `MATCH` clause while extracting paths
在我解释我面临的问题之前,我认为如果我解释一下我的图形数据库的结构会更好。以下是我的 neo4j
图形数据库中的节点、关系和属性:
节点:
- 用户
- 电子邮件
- Phone
- 图书
- 博文
关系:
- HAS(用作:用户 -[:HAS]-> (e:Email|Phone))
- READ(用作:用户 - [:READ] -> (b:Book|BlogPost))
- WROTE(用作:用户 - [:WROTE] -> (b:Book|BlogPost))
属性:
- uid(与节点 User、Book、BlogPost、Email,Phone)
- 名称(与节点用户关联)
- 标题(与节点 Book、BlogPost 相关联)
- 电子邮件(与节点电子邮件关联)
- phone(与节点 Phone 关联)
在我真正提出我的问题之前,我想声明我对 neo4j 技术还很陌生,所以我明白我的问题的解决方案可能是基本的。
我想达到什么目的?
我想获得两个用户之间的所有最短路径,然后对于我想获得的路径中这两个用户之间的每个节点:
- 电子邮件地址 and/or phone 如果节点是用户节点。
- 节点的标题,如果它是 Book 或 BlogPost 节点。
我卡在哪里了?
我可以使用以下密码查询获取路径:
match (u1: User {uid: '0001'}),
(u2: User{uid: '0002'}),
paths = allShortestPaths((u1)-[*..4]-(u2))
return paths
获取路径后,如果我按如下方式修改上述查询,我可以使用 extract
、nodes
、relationships
函数获取节点的属性、路径中的关系:
match (u1: User {uid: '0001'}),
(u2: User{uid: '0002'}),
paths= allShortestPaths((u1)-[*..4]-(u2))
with extract(n in nodes(paths) | [n.name]) as nds,
extract(r in relationships(paths)| [type(r)]) as rels
return nds,rels
问题
但我真正想要得到的是 email
和 phone
属性关闭 Email
和 Phone
节点,这些节点连接到给定路径内的任何节点。
我浏览了 official documentation 和很多博客文章,但找不到任何解决方案或类似问题。
如何实现上述目标?
PS: 我想在一个查询中实现这个
谢谢
这样的东西能满足您的需求吗?
以下主要编辑:
在下面的 return 语句中:
- 获取路径中不包括第一个和最后一个节点的节点列表
- 使用标签仅检查用户、图书和博客文章
- 将中间用户节点过滤为一个collection
- 过滤掉中间 book/blog 个帖子并将标题提取到另一个 collection
- 遍历中间用户节点以查找关联的电子邮件和/或 phone 节点(信用@FrobberOfBits)
这是密码:
// match the user nodes and the shortest intermediate paths between them
match (u1:User {uid: '0001'})
, (u2:User {uid: '0002'})
, path = allShortestPaths((u1)-[*..4]-(u2))
// filter out the intermediate user nodes into one collection
with filter(n IN nodes(path)[1..length(nodes(path))-1]
where any(x in labels(n) where x = 'User'))
as intermediate_users
// filter out the intermediate book titles into another collection
, [n IN nodes(path)[1..length(nodes(path))-1]
where any(x in labels(n) where x in ['Book','BlogPost'])
| n.title ]
as intermediate_books_posts
// iterate through the intermediate user nodes
// and optionally match email and phone nodes
unwind intermediate_users as u
optional match (e:Email)<--u-->(p:Phone)
return u.name, e.address, p.number, intermediate_books_posts
在我解释我面临的问题之前,我认为如果我解释一下我的图形数据库的结构会更好。以下是我的 neo4j
图形数据库中的节点、关系和属性:
节点:
- 用户
- 电子邮件
- Phone
- 图书
- 博文
关系:
- HAS(用作:用户 -[:HAS]-> (e:Email|Phone))
- READ(用作:用户 - [:READ] -> (b:Book|BlogPost))
- WROTE(用作:用户 - [:WROTE] -> (b:Book|BlogPost))
属性:
- uid(与节点 User、Book、BlogPost、Email,Phone)
- 名称(与节点用户关联)
- 标题(与节点 Book、BlogPost 相关联)
- 电子邮件(与节点电子邮件关联)
- phone(与节点 Phone 关联)
在我真正提出我的问题之前,我想声明我对 neo4j 技术还很陌生,所以我明白我的问题的解决方案可能是基本的。
我想达到什么目的?
我想获得两个用户之间的所有最短路径,然后对于我想获得的路径中这两个用户之间的每个节点:
- 电子邮件地址 and/or phone 如果节点是用户节点。
- 节点的标题,如果它是 Book 或 BlogPost 节点。
我卡在哪里了?
我可以使用以下密码查询获取路径:
match (u1: User {uid: '0001'}),
(u2: User{uid: '0002'}),
paths = allShortestPaths((u1)-[*..4]-(u2))
return paths
获取路径后,如果我按如下方式修改上述查询,我可以使用 extract
、nodes
、relationships
函数获取节点的属性、路径中的关系:
match (u1: User {uid: '0001'}),
(u2: User{uid: '0002'}),
paths= allShortestPaths((u1)-[*..4]-(u2))
with extract(n in nodes(paths) | [n.name]) as nds,
extract(r in relationships(paths)| [type(r)]) as rels
return nds,rels
问题
但我真正想要得到的是 email
和 phone
属性关闭 Email
和 Phone
节点,这些节点连接到给定路径内的任何节点。
我浏览了 official documentation 和很多博客文章,但找不到任何解决方案或类似问题。
如何实现上述目标?
PS: 我想在一个查询中实现这个
谢谢
这样的东西能满足您的需求吗?
以下主要编辑:
在下面的 return 语句中:
- 获取路径中不包括第一个和最后一个节点的节点列表
- 使用标签仅检查用户、图书和博客文章
- 将中间用户节点过滤为一个collection
- 过滤掉中间 book/blog 个帖子并将标题提取到另一个 collection
- 遍历中间用户节点以查找关联的电子邮件和/或 phone 节点(信用@FrobberOfBits)
这是密码:
// match the user nodes and the shortest intermediate paths between them
match (u1:User {uid: '0001'})
, (u2:User {uid: '0002'})
, path = allShortestPaths((u1)-[*..4]-(u2))
// filter out the intermediate user nodes into one collection
with filter(n IN nodes(path)[1..length(nodes(path))-1]
where any(x in labels(n) where x = 'User'))
as intermediate_users
// filter out the intermediate book titles into another collection
, [n IN nodes(path)[1..length(nodes(path))-1]
where any(x in labels(n) where x in ['Book','BlogPost'])
| n.title ]
as intermediate_books_posts
// iterate through the intermediate user nodes
// and optionally match email and phone nodes
unwind intermediate_users as u
optional match (e:Email)<--u-->(p:Phone)
return u.name, e.address, p.number, intermediate_books_posts