在提取路径时使用`WITH`或`MATCH`子句

时间:2015-04-21 12:55:18

标签: neo4j cypher

在我解释我面临的问题之前,我认为如果我稍微解释一下我的图形数据库的结构会更好。以下是我的neo4j图数据库中的节点,关系和属性:

节点:

  • 用户
  • 电子邮件
  • 电话
  • 博文

的关系:

  • HAS(用作: 用户 - [:HAS] - >(e:电子邮件|电话)
  • READ(用作: 用户 - [:READ] - >(b:图书| BlogPost)
  • WROTE(用作: 用户 - [:WROTE] - >(b:Book | BlogPost)

属性:

  • uid(与节点User,Book,BlogPost,Email,Phone相关联)
  • 名称(与节点用户关联)
  • title(与节点Book,BlogPost相关联)
  • 电子邮件(与节点电子邮件关联)
  • 电话(与节点电话相关联)

在我真正提出我的问题之前,我想说明我对neo4j技术很陌生,所以我确实理解我的问题的解决方案可能是基本的。

我想要实现的目标是什么?

我想获得两个用户之间的所有最短路径,然后为我希望得到的路径中的这两个用户之间的每个节点:

  • 如果节点是用户节点,则为电子邮件地址和/或电话号码。
  • 节点的标题,如果它是Book或BlogPost节点。

我被困在哪里?

我可以使用以下cypher查询获取路径:

match (u1: User {uid: '0001'}),
(u2: User{uid: '0002'}),
paths = allShortestPaths((u1)-[*..4]-(u2))
return paths

获取路径后,如果我按以下方式修改上述查询,我​​可以使用extractnodesrelationships函数获取节点的属性,路径中的关系:< / p>

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

问题

但我真正希望得到的是emailphone属性关闭EmailPhone个节点,它们连接到给定路径中的任何节点。

我已经浏览了official documentation和很多博客帖子,但找不到任何解决方案或类似的问题。

如何实现上述目标?

PS:我想在一次查询中实现这一目标

由于

1 个答案:

答案 0 :(得分:3)

这样的事情是否满足您的需求?

主要编辑如下:

在下面的回复声明中:

  • 获取路径中的节点列表,不包括第一个和最后一个节点
  • 使用标签仅检查用户,书籍和博客帖子
  • 将中间用户节点过滤为一个集合
  • 过滤掉中级书籍/博客帖子并将标题提取到另一个集合
  • 遍历中间用户节点以查找关联的电子邮件和/或电话节点(credit @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