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

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

neo_ga3

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

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

2013-10-25_16-34-16

我们可以使用以下密码语法在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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/366536.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

复旦大学计算机学院博士生王斌,复旦大学计算机科学技术学院博士生刘鹏飞荣获...

计算机科学技术学院发布时间:2017-01-04 小字体 中字体 大字体2016年12月22日,历时七个月选拔的2016年度百度奖学金获奖者揭晓,复旦大学计算机科学技术学院2014级博士生刘鹏飞以其在“自然语言处理与深度学习”上取得的突出成绩,从国内外近百所著名高校数百位竞争者中脱颖而出,…

Deno 兼容浏览器具体指的是什么?

Deno 里面有一句描述&#xff1a;"Aims to be browser compatible"&#xff0c;可以看到 Deno 的目标是兼容浏览器。那么这里的兼容浏览器到底如何是什么意思呢&#xff1f; 我简单谈谈我的理解吧。 首先这里的兼容性肯定不是 Deno 直接在浏览器端运行。因为 Deno …

判断按键值_「正点原子NANO STM32开发板资料连载」第十六章电容触摸按键实验...

1&#xff09;实验平台&#xff1a;ALIENTEK NANO STM32F411 V1开发板2&#xff09;摘自《正点原子STM32F4 开发指南&#xff08;HAL 库版》关注官方微信号公众号&#xff0c;获取更多资料&#xff1a;正点原子第十六章电容触摸按键实验上一章&#xff0c;我们介绍了 STM32F4 的…

将社交登录添加到Spring MVC Web应用程序:注册和登录

本教程的第一部分描述了如何配置Spring Social 1.1.0和Spring Security 3.2.0&#xff0c;但它留下了两个非常重要的问题尚未解答。 这些问题是&#xff1a; 用户如何创建新用户帐户&#xff1f; 用户如何登录&#xff1f; 现在该弄脏我们的手并回答这些问题了。 我们的示例…

实验五 编写、调试具有多个段的程序

&#xff08;1&#xff09;将下面的程序编译、连接&#xff0c;用Debug加载、跟踪&#xff0c;然后回答问题。 ①CPU执行程序&#xff0c;程序返回前&#xff0c;data段的数据为多少&#xff1f; 见下图d 0770:0000 000f结果。 ②CPU执行程序&#xff0c;程序返回前&#xff0c…

手机工商银行怎么转账_工商银行信用卡要哪些申请条件?想成功办理你需要了解这些!...

工商银行信用卡一直是卡友们热议的对象&#xff0c;也有不少卡友问过小白&#xff1a;工商银行信用卡怎么办理&#xff1f;要哪些条件&#xff1f;要等多长时间&#xff1f;那么今天小白就为大家详细的讲解一下工商银行信用卡申请的各种方法和技巧&#xff0c;希望对大家有帮助…

数据可视化的基本原理——视觉通道

数据可视化为了达到增强人脑认知的目的&#xff0c;会利用不同的视觉通道对冰冷的数据进行视觉编码。 我们在数据可视化的时候&#xff0c;一方面&#xff0c;展现可视化对象本身的位置、特性&#xff0c;对应的视觉通道类型是定性或者分类&#xff0c;比如汽车在什么地方、汽…

linux测试地址是否能访问_一个小测试能看出孩子注意力是否集中,提前弥补,上小学会很轻松...

文|秘籍君不少家长虽然重视孩子的教育&#xff0c;却总是习惯“临阵磨枪”&#xff0c;具体体现在&#xff1a;孩子在上幼儿园的前一两个月才开始着急&#xff0c;害怕孩子适应不了幼儿园&#xff1b;孩子上了大班才开始重视“幼小衔接”&#xff0c;却不知道&#xff0c;从孩子…

服务器怎么禁止iis静态文件,如何禁止IIS缓存静态文件

禁止IIS缓存静态文件(png、js、html等)背景&#xff1a;IIS为了提高性能&#xff0c;默认情况下会对静态文件js、html、gif、png等做内部缓存&#xff0c;这个缓存是在服务器iis进程的内存中的。IIS这么做在很大程度上可以提高静态文件的访问性能&#xff0c;在正常情况下只要静…

汇编实验五

一、 二、 三、 四、 第一个 反汇编后发现不行 第二个 发现也不行 第三个 发现代码正确 五、 编写代码如下 调试后查看内存&#xff0c;发现数据相加了 六、 编写代码如下 发现逆序存储成功 七、实验总结 对于代码段的使用有了更加深入的了解。 但是对于代码段内存这块还是不懂…

eclipse RTC下载的代码无android sdk

问题现象&#xff1a; 修复过程&#xff1a; 1.无ADT&#xff0c;安装ADT&#xff08;FQ操作&#xff09; https://dl-ssl.google.com/android/eclipse/ a图 b图 2.下载android sdk a.下载 3.应用到eclipse中去 转载于:https://www.cnblogs.com/liuyj-vv/p/9299913.html

亚马逊免费使用套餐:在EC2 Linux实例上安装Tomcat 7

Amazon Web Services提供了12个月的免费使用期限&#xff0c;使开发人员可以在云中运行任何他们想要的东西。 免费层包括14个服务&#xff0c;其中Web开发人员最关注EC2服务。 EC2是一项服务&#xff0c;通过停止和启动Windows和/或Linux的虚拟实例来提供可调整大小的虚拟计算。…

笔记:隐式转换规则

学习并背诵全文 原始值 类型UndefinedNullStringBooleanNumber值undefinednull所有字符串true false所有数字/NaN 引用类型 Object的成员叫对象&#xff0c;包括Array&#xff0c;Function&#xff0c;Math&#xff0c;Date&#xff0c;JSON&#xff0c;RegExp等除了原始值…

ble连接过程建立_九点之蓝牙连接

蓝牙连接蓝牙连接是如何进入到连接状态呢&#xff0c;首先必须经历前面提到的广播阶段&#xff0c;主端通过扫描到从端的广播来发现这个设备&#xff0c;之后让主端发出连接请求来要求与从端建立连接&#xff0c;便可以进入到连接状态。由于蓝牙连接牵涉的点比较多&#xff0c;…

华为服务器系统蓝屏,服务器主机蓝屏

服务器主机蓝屏 内容精选换一换云服务器创建后区域固定&#xff0c;不能将云服务器转移到另一个区域&#xff0c;也不能将云服务器转移到另一个帐号。您可以通过镜像迁移方式实现云服务器的跨帐号跨区域迁移。服务器迁移的常见场景与常用的迁移方式请参考常见的服务器迁移场景。…

多对一映射、一对多映射

Emp员工表 Dept部门表 多对一映射 在查询时&#xff0c;需要获取两张以上关联表的数据&#xff0c;通过关联映射&#xff0c;可以由一个对象获取关联对象的信息&#xff0c;例如&#xff1a;查询一个Emp员工对象&#xff0c;可以 通过关联映射获取员工所在的部门Dept对象信息 …

一道面试题目引发的思考

起因 多列布局是前端一个经典的反复被提及的面试题目&#xff0c;最典型的即两列&#xff0c;左列定宽菜单栏&#xff0c;右列变宽为内容区域。 通常得到的答案无外乎左列浮动定宽&#xff0c;然后右列或浮动&#xff0c;或设置外边距&#xff0c;或绝对定位等等。偶尔会有面试…

uniapp弹出框_uniApp上拉刷新,下拉加载,以及筛选功能

uniApp插件市场有很多友好的插件&#xff0c;今天举一个例子如上图所示&#xff0c;实现上拉刷新&#xff0c;下来加载&#xff0c;右上角点击弹出筛选框&#xff0c;只需要在插件市场搜索刷新选择你想要的效果(也可以下载后自己改动效果)点击导入插件&#xff0c;会自动打开项…

乐高无限的服务器怎么建,乐高无限悬空房子怎么建造 建造方法介绍

乐高无限悬空房子怎么建造?很多玩家对此还不是很清楚&#xff0c;下面给大家带来乐高无限悬空房子建造方法&#xff0c;还不知道怎么建造的朋友一起来看看吧!建造方法悬空房子非常容易搭建&#xff0c;如果我们想要将已经搭建的房子悬空&#xff0c;就只需要将建筑下方的土地挖…

Hibernate学习(一)

搭建环境 1、创建普通的Java工程 2、添加相应的jar包&#xff0c;下载链接&#xff1a;https://files.cnblogs.com/files/AmyZheng/required.rar 第一个实例 1、引用jar包 2、创建数据库和表 DROP TABLE IF EXISTS t_customer ;CREATE TABLE t_customer (id INT(5) PRIMARY KE…