最近,我阅读了Michal Bachman关于 Neo4j中双向关系的文章 ,他建议对于某些关系类型,我们对关系的方向不那么感兴趣,因此可以在查询时忽略它。 他使用以下示例显示了Neo Technology和GraphAware之间的合作关系:

两家公司都是彼此的合作伙伴,但是由于我们可以尽快找到传入和传出的关系,因此我们最好在两家公司/节点之间只有一种关系。

当我们想使图中的隐式关系明确时,经常会出现这种模式。 例如,我们可能有以下图形描述了他们所从事的人员和项目:

我们可以使用以下密码语法在Neo4j 2.0中创建该图:

CREATE (mark:Person {name: "Mark"})
CREATE (dave:Person {name: "Dave"})
CREATE (john:Person {name: "John"})CREATE (projectA:Project {name: "Project A"})
CREATE (projectB:Project {name: "Project B"})
CREATE (projectC:Project {name: "Project C"})CREATE (mark)-[:WORKED_ON]->(projectA)
CREATE (mark)-[:WORKED_ON]->(projectB)
CREATE (dave)-[:WORKED_ON]->(projectA)
CREATE (dave)-[:WORKED_ON]->(projectC)
CREATE (john)-[:WORKED_ON]->(projectC)
CREATE (john)-[:WORKED_ON]->(projectB)

如果我们想弄清楚哪些人彼此认识,我们可以编写以下查询:

MATCH (person1:Person)-[:WORKED_ON]-()<-[:WORKED_ON]-(person2)
RETURN person1, person2==> +-------------------------------------------------------+
==> | person1                   | person2                   |
==> +-------------------------------------------------------+
==> | Node[500363]{name:"Mark"} | Node[500364]{name:"Dave"} |
==> | Node[500363]{name:"Mark"} | Node[500365]{name:"John"} |
==> | Node[500364]{name:"Dave"} | Node[500363]{name:"Mark"} |
==> | Node[500364]{name:"Dave"} | Node[500365]{name:"John"} |
==> | Node[500365]{name:"John"} | Node[500364]{name:"Dave"} |
==> | Node[500365]{name:"John"} | Node[500363]{name:"Mark"} |
==> +-------------------------------------------------------+
==> 6 rows

我们可能要在每对人之间创建一个KNOWS关系:

MATCH (person1:Person)-[:WORKED_ON]-()<-[:WORKED_ON]-(person2)
CREATE UNIQUE (person1)-[:KNOWS]->(person2)
RETURN person1, person2

现在,如果我们运行一个查询(忽略关系方向)以找出哪些人彼此认识,我们将得到很多重复的结果:

MATCH path=(person1:Person)-[:KNOWS]-(person2)
RETURN person1, person2, path==> +--------------------------------------------------------------------------------------------------------------------------------+
==> | person1                   | person2                   | path                                                                   |
==> +--------------------------------------------------------------------------------------------------------------------------------+
==> | Node[500363]{name:"Mark"} | Node[500364]{name:"Dave"} | [Node[500363]{name:"Mark"},:KNOWS[528536]{},Node[500364]{name:"Dave"}] |
==> | Node[500363]{name:"Mark"} | Node[500365]{name:"John"} | [Node[500363]{name:"Mark"},:KNOWS[528537]{},Node[500365]{name:"John"}] |
==> | Node[500363]{name:"Mark"} | Node[500364]{name:"Dave"} | [Node[500363]{name:"Mark"},:KNOWS[528538]{},Node[500364]{name:"Dave"}] |
==> | Node[500363]{name:"Mark"} | Node[500365]{name:"John"} | [Node[500363]{name:"Mark"},:KNOWS[528541]{},Node[500365]{name:"John"}] |
==> | Node[500364]{name:"Dave"} | Node[500363]{name:"Mark"} | [Node[500364]{name:"Dave"},:KNOWS[528538]{},Node[500363]{name:"Mark"}] |
==> | Node[500364]{name:"Dave"} | Node[500365]{name:"John"} | [Node[500364]{name:"Dave"},:KNOWS[528539]{},Node[500365]{name:"John"}] |
==> | Node[500364]{name:"Dave"} | Node[500363]{name:"Mark"} | [Node[500364]{name:"Dave"},:KNOWS[528536]{},Node[500363]{name:"Mark"}] |
==> | Node[500364]{name:"Dave"} | Node[500365]{name:"John"} | [Node[500364]{name:"Dave"},:KNOWS[528540]{},Node[500365]{name:"John"}] |
==> | Node[500365]{name:"John"} | Node[500364]{name:"Dave"} | [Node[500365]{name:"John"},:KNOWS[528540]{},Node[500364]{name:"Dave"}] |
==> | Node[500365]{name:"John"} | Node[500363]{name:"Mark"} | [Node[500365]{name:"John"},:KNOWS[528541]{},Node[500363]{name:"Mark"}] |
==> | Node[500365]{name:"John"} | Node[500363]{name:"Mark"} | [Node[500365]{name:"John"},:KNOWS[528537]{},Node[500363]{name:"Mark"}] |
==> | Node[500365]{name:"John"} | Node[500364]{name:"Dave"} | [Node[500365]{name:"John"},:KNOWS[528539]{},Node[500364]{name:"Dave"}] |
==> +--------------------------------------------------------------------------------------------------------------------------------+
==> 12 rows

每对人出现4次,如果我们以Mark和Dave为例,我们可以看到原因:

MATCH path=(person1:Person)-[:KNOWS]-(person2)
WHERE person1.name = "Mark" AND person2.name = "Dave"
RETURN person1, person2, path==> +--------------------------------------------------------------------------------------------------------------------------------+
==> | person1                   | person2                   | path                                                                   |
==> +--------------------------------------------------------------------------------------------------------------------------------+
==> | Node[500363]{name:"Mark"} | Node[500364]{name:"Dave"} | [Node[500363]{name:"Mark"},:KNOWS[528536]{},Node[500364]{name:"Dave"}] |
==> | Node[500363]{name:"Mark"} | Node[500364]{name:"Dave"} | [Node[500363]{name:"Mark"},:KNOWS[528538]{},Node[500364]{name:"Dave"}] |
==> +--------------------------------------------------------------------------------------------------------------------------------+
==> 2 rows

如果我们看一下路径栏下有两个不同的KNOWS关系(与IDS 528536和528538),马克和戴夫,一个去之间从马克戴夫和其他来自Dave马克。

正如Michal在他的帖子中指出的那样,在这种情况下,不需要两个关系。 我们只需要一种关系,可以通过创建KNOWS关系时不指定方向来实现:

MATCH (person1:Person)-[:WORKED_ON]-()<-[:WORKED_ON]-(person2)
CREATE UNIQUE (person1)-[:KNOWS]-(person2)
RETURN person1, person2

现在,如果我们重新运行查询以检查Mark和Dave之间的关系,则只有一个:

MATCH path=(person1:Person)-[:KNOWS]-(person2) WHERE person1.name = "Mark" AND person2.name = "Dave" RETURN person1, person2, path==> +--------------------------------------------------------------------------------------------------------------------------------+
==> | person1                   | person2                   | path                                                                   |
==> +--------------------------------------------------------------------------------------------------------------------------------+
==> | Node[500375]{name:"Mark"} | Node[500376]{name:"Dave"} | [Node[500375]{name:"Mark"},:KNOWS[528560]{},Node[500376]{name:"Dave"}] |
==> +--------------------------------------------------------------------------------------------------------------------------------+
==> 1 row

在这种情况下,关系从Mark到Dave,可以通过执行一些考虑方向的查询来看到:

MATCH path=(person1:Person)-[:KNOWS]->(person2)
WHERE person1.name = "Mark" AND person2.name = "Dave"
RETURN person1, person2, path==> +--------------------------------------------------------------------------------------------------------------------------------+
==> | person1                   | person2                   | path                                                                   |
==> +--------------------------------------------------------------------------------------------------------------------------------+
==> | Node[500375]{name:"Mark"} | Node[500376]{name:"Dave"} | [Node[500375]{name:"Mark"},:KNOWS[528560]{},Node[500376]{name:"Dave"}] |
==> +--------------------------------------------------------------------------------------------------------------------------------+
==> 1 row
MATCH path=(person1:Person)<-[:KNOWS]-(person2)
WHERE person1.name = "Mark" AND person2.name = "Dave"
RETURN person1, person2, path==> +--------------------------+
==> | person1 | person2 | path |
==> +--------------------------+
==> +--------------------------+
==> 0 row
参考: Neo4j:通过Mark Needham博客博客的JCG合作伙伴 Mark Needham 使隐式关系成为显式和双向关系 。

翻译自: https://www.javacodegeeks.com/2013/10/neo4j-making-implicit-relationships-explicit-bidirectional-relationships.html

Neo4j:使隐式关系成为显式和双向关系相关推荐

  1. intent隐式和显式_Neo4j:使隐式关系成为显式和双向关系

    intent隐式和显式 我最近阅读了Michal Bachman关于 Neo4j中双向关系的文章 ,他建议对于某些关系类型,我们对关系的方向不那么感兴趣,因此可以在查询时忽略它. 他使用以下示例显示N ...

  2. Python网络爬虫Selenium页面等待:强制等待、隐式等待和显式等待

    关于Python网络爬虫Selenium强制等待.隐式等待和显式等待的总结 from selenium import webdriver import time from selenium.webdr ...

  3. js 中的this,默认绑定、隐式绑定、显式绑定、new绑定、箭头函数绑定详解

    壹 ❀ 引 工具猴-免费在线工具-在线工具箱- 可以说this与闭包.原型链一样,属于JavaScript开发中老生常谈的问题了,百度一搜,this相关的文章铺天盖地.可开发好几年,被几道this题安 ...

  4. 五种绑定彻底弄懂this,默认绑定、隐式绑定、显式绑定、new绑定、箭头函数绑定详解

    壹 ❀ 引 可以说this与闭包.原型链一样,属于JavaScript开发中老生常谈的问题了,但开发好几年,依然被几道this指向题安排明明白白的人应该不在少数.对于初学者而言,this概念抽象,变化 ...

  5. Oracle隐式游标和显式游标

    游标是什么?就是在内存开辟的一块临时存储空间. 1.Oracle隐式游标 1.1Oracle有常用的哪些隐式游标 1.2 Oracle隐式游标演示 -- 隐式游标 (使用的表为Oracle默认自带的e ...

  6. oracle 游标内存自动释放,详解Oracle隐式游标和显式游标

    游标是什么?就是在内存开辟的一块临时存储空间. 1.Oracle隐式游标 1.1Oracle有常用的哪些隐式游标 1.2 Oracle隐式游标演示 -- 隐式游标 (使用的表为Oracle默认自带的e ...

  7. Selenium中的隐式等待和显式等待

    在Selenium中,"等待"在执行测试中起着重要作用.在本文中,您将学习Selenium中"隐式"和"显式"等待的各个方面. 在本文中,您 ...

  8. Selenium4+Python3系列 - Selenium的三种等待,强制等待、隐式等待、显式等待

    为什么要设置元素等待 直白点说,怕报错,哈哈哈! 肯定有人会说,这也有点太直白了吧. 用一句通俗易懂的话就是:等待元素已被加载完全之后,再去定位该元素,就不会出现定位失败的报错了. 如何避免元素未加载 ...

  9. 自动化测试中,三种常用的等待方式,强制式(sleep) 、 隐式 ( implicitly_wait ) 、显式(expected_conditions)

       在自动化测试总,主要有三种常用的等待方式,强制式(sleep) . 隐式 ( implicitly_wait ) .显式(expected_conditions). 一.强制式(sleep)   ...

最新文章

  1. mysql远程连接工具 cen_Navicat远程连接Centos数据库Mysql
  2. c语言usb串口输出,C语言实现模拟USB对8bit数据的NRZI编码输出
  3. mysql 执行计划extra_MySQL执行计划extra中的using index 和 using where using index 的区别...
  4. (0078)iOS开发之支付宝集成:客户端签名与验证
  5. SAP Classification(物料特性)
  6. how to find annual report for a stock market company
  7. Hexo创建导航页面
  8. 剑网三缘起,葱姜蒜也能卖?欺负新玩家被批评,但说明游戏很自由
  9. Android之Service
  10. 告别只会调参和调包,全球顶会论文审稿人带你7天玩转图像分割
  11. numpy—np.info(function)
  12. getopt/getopt_long函数使用说明
  13. java jpa面试题_jpa面试题解析,java面试题
  14. 用matlab辨识系统,Matlab系统辨识工具箱
  15. python识别图像中的文字并点击_Python图像处理之识别图像中的文字(实例讲解)
  16. 31道Java核心面试题(不会的都看过来啦)
  17. 垃圾回收器——CMS与G1
  18. java判断生日_java根据生日判断生日和星座
  19. 计算机网络-什么是因特网
  20. MySQL根据某一个字段合并重复列

热门文章

  1. 磁珠 符号_贴片磁珠功能_贴片磁珠应用
  2. 从oracle里面取直,45个非常有用的 Oracle 查询语句小结
  3. java本地连接zk集群
  4. tomcat(3)连接器
  5. XML——XSLT的一个简单荔枝
  6. 搭建一个简单的Spring boot+maven项目
  7. java jvm虚拟机_Java虚拟机(JVM)简介
  8. openshift_Openshift源中的高可用性Drools无状态服务
  9. 组件注入 # 注入的属性_注入域对象而不是基础结构组件
  10. intellij 快捷键_IntelliJ中的键盘快捷键