intent隐式和显式

我最近阅读了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次,如果我们以马克和戴夫为例,我们可以看到原因:

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

intent隐式和显式

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

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

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

  2. linux下动态链接库(.so)的显式调用和隐式调用

    进入主题前,先看看两点预备知识. 一.显式调用和隐式调用的区别 我们知道,动态库相比静态库的区别是:静态库是编译时就加载到可执行文件中的,而动态库是在程序运行时完成加载的,所以使用动态库的程序的体积要 ...

  3. C++---显示实例化与隐式实例化,显示调用与隐式调用

    出现场景:C++模板中 template<class T> T Add(T left,T right)return left+right; 上述代码只有经过实例化之后才会形成真正的函数,没 ...

  4. 三相桥式全控整流电路原理及电路图,三相桥式全控整流电路原理及电路图

    三相桥式全控整流电路原理及电路图,三相桥式全控整流电路原理及电路图 三相整流电路的作用: 在电路中,当功率进一步增加或由于其他原因要求多相整流时,三相整流电路就被提了出来.图所示就是三相半波整流电路原 ...

  5. 非抢占式优先级调度算法_华为鸿蒙操作系统内核真面目之抢占式和非抢占式内核...

    华为鸿蒙操作系统内核真面目之抢占式和非抢占式内核 众所周知华为鸿蒙操作系统内核是Linux内核.而Linux内核即是抢占式内核也是非抢占式内核.设置软件优先级在优先级在0-99之间是抢占式优先级.设置 ...

  6. 逻辑式编程语言极简实现(使用C#) - 1. 逻辑式编程语言介绍

    逻辑式编程语言极简实现(使用C#) - 1. 逻辑式编程语言介绍 相信很多朋友对于逻辑式编程语言,都有一种最熟悉的陌生人的感觉.一方面,平时在书籍.在资讯网站,偶尔能看到一些吹嘘逻辑式编程的话语.但另 ...

  7. 响应式布局必懂知识_五分钟教会你响应式布局

    第一:正确理解响应式布局 第二:响应式设计基本步骤 第三:响应式设计注意事项 第四:响应式布局实现原理 第一:正确理解响应式布局 响应式网页设计就是一个网站能够兼容多个终端,而不是为每个终端都做一个特 ...

  8. 怎么看计算机内存和独显,电脑独立显卡或集成显卡的显存大小怎么查看?

    我们有时候想要查看自己电脑显卡的显存大小,当然现在的显卡通常有两种,独立显卡和集成显卡,集成显卡是集成到电脑主板上的,怎么查看电脑显卡显存的大小呢?我们可以用很多方法来进行查看,当然通常的集成显卡本身 ...

  9. 计算机专业独显好还是集显好,笔记本选购指南:笔记本电脑核显好还是独显好?...

    暑期装机热潮来了,而大部分大学生会选择入手一台笔记本而不是笨重的台式机,今天这里主要讲下笔记本选购指南,笔记本电脑核显好还是独显好? 可能这个问题提出来,大家就要说很外行.不过既然是写给不太懂电脑的人 ...

最新文章

  1. html最新的版本是多少,HTML5之前的版本是什么?
  2. 关于对 NUMA 理解(学习笔记,便于以后查阅)
  3. 剑指Offer(Java实现)扑克牌顺子
  4. Leetcode 130. 被围绕的区域 (每日一题 20210720 同类型题)
  5. 正经炼丹师如何完美安排国庆长假?| 假期专属论文清单
  6. Android ---- Context
  7. linux+cd英文全称,Linux命令英文全称
  8. redis存储对象_redis内存优化总结
  9. 常用DOS下MSC指令
  10. 技术人 | 我在支付宝体验技术部这四年学到了什么?
  11. 【软考】2019 上半年软件设计师 下午真题及答案
  12. 基于SSM+Layui图书借阅管理系统设计
  13. python语言是不是胶水语言_不会吧,不会吧,不会还有人觉得Python是胶水语言吧?...
  14. SPSS学习 相关性分析
  15. 什么是Java api
  16. 使用OpenVINO部署ONNX模型
  17. vue 跳转到指定路由地址 (可附带参数)
  18. 用计算机画函数,用计算机画函数图像 优质课教案设计
  19. Python简易的HTTP服务器
  20. win10计算机本地连接属性在哪里,Win10系统怎么打开本地连接属性

热门文章

  1. 2018-2019 ACM—ICPC SEERC 题解
  2. DevOps之发布系统
  3. MyBatis-generator使用,Example缺少分页问题解决
  4. 汇编语言(六)之输出字符的前导后字符
  5. Class类中的getEnclosingXX、getDeclaredXX
  6. Spring AOP注解为什么失效?90%Java程序员不知道
  7. JDK8新特性之重复注解
  8. 2017派卧底去阿里、京东、美团、滴滴带回来的面试题
  9. 漫画:什么是MapReduce
  10. React中解决样式丢失问题