读图数据库实战笔记04_路径与图变异

news2024/11/16 3:23:46

1. Groovy

1.1. Java编程语言的一个超集

1.2. Gremlin Console的一个特性是能和Groovy配合使用

1.2.1. Gremlin Console会自动地迭代结果

1.3. 从技术上说,Gremlin Console就是Groovy交互式解释器(read-eval-print loop,REPL)

1.3.1. 既可以作为一个独立的程序运行,也可以很容易地在其他程序中作为整体程序的一部分使用

2. 变异(mutation)

2.1. 简单地被理解为通过添加、修改或删除顶点、边和/或属性来改变图

2.2. 变异遍历或变异过程是在某种程度上改变图的内容或结构的操作

3. 添加顶点

3.1. INSERT INTO person (first_name) VALUES ('Dave');

3.2. 在图中添加顶点相当于在关系数据库中添加实体

3.3. 过程

3.3.1. 给定一个遍历源g

3.3.2. 添加一个新的顶点,类型是person

3.3.3. 在该顶点上添加一个属性,键是first_name,值是Dave

3.4. groovy

g.addV('person').property('first_name', 'Dave')
==>v[13]

3.4.1. 只需要为每一个addV()操作增加一个单一顶点

3.4.2. addV(label)

3.4.2.1. 在图中增加一个类型为label的顶点并返回这个新增顶点的引用

3.4.3. property(key, value)

3.4.3.1. 在顶点或边上增加一个属性
3.4.3.2. 该属性包含指定的key和value
3.4.3.3. 返回对进入该操作的顶点或边的引用

3.4.4. v[13]

3.4.4.1. 顶点的唯一的识别码
3.4.4.2. 这个ID值是根据数据库的当前状态内部生成的
3.4.4.2.1. 顶点的ID值应该被视为图数据库引擎的内部信息
3.4.4.2.2. 对数据库引擎等工具的内部信息,你应该保持足够的警惕
3.4.4.2.3. 为了应用程序的需要而在应用代码中使用它们则是极其危险的
3.4.4.3. Gremlin Server,在顶点上使用简单整数(32位),在边上使用长整数(64位)
3.4.4.4. 其他图数据库引擎可能会使用UUID或GUID
3.4.4.5. 虽然可以在代码中运用这些值,但最佳实践是不去使用它们

3.5. g.V().addV('person')

3.5.1. V()操作不仅代表图中的所有顶点,也会返回所有顶点

3.5.1.1. 下一个操作将在上一步操作输出的每个元素上执行

3.5.2. 图中的每一个现有顶点都会被添加一个person顶点

3.5.3. 在某些情况下,这可能是我们想要的结果

4. 添加边

4.1. 在关系数据库世界里,实体间的连接是通过外键隐式实现的

4.2. 在图的世界里,这些连接需要通过边来显式添加

4.3. 在添加边时,需要为它指定入顶点和出顶点

4.4. SELECT * FROM table1 WHERE id = (SELECT id1 FROM table2);

4.5. 过程

4.5.1. 给定一个遍历源g

4.5.2. 添加一条标签为friends的边

4.5.3. 分配边的出顶点是键为first_name、值为Ted的顶点

4.5.4. 分配边的入顶点是键为first_name、值为Hank的顶点

4.6. groovy

g.addE('friends').
  from(
    V().has('person', 'first_name', 'Ted')
  ).
  to(
    V().has('person', 'first_name', 'Hank')
  )
==>e[15][4-friends->6]

4.6.1. addE(label)

4.6.1.1. 添加一条标签为label的边

4.6.2. from(vertex)

4.6.2.1. 指定边从哪个顶点开始的调节器

4.6.3. to(vertex)

4.6.3.1. 指定边在哪个顶点结束的调节器

4.6.4. 操作调节器不能单独使用

4.6.5. 调节器来源于TinkerPop,但提供开始顶点和结束顶点的细节则是通用需求

5. 删除顶点

5.1. DELETE FROM person WHERE person_id = 13;

5.2. 过程

5.2.1. 给定一个遍历源g

5.2.2. 找到一个ID为13的顶点

5.2.3. 删除这个顶点

5.3. g.V(13).drop()

5.3.1. V(id)

5.3.1.1. 返回id指定的顶点
5.3.1.2. 这个id是由Gremlin Server(其选择的数据库)分配和维护的内部ID

5.3.2. drop()

5.3.2.1. 删除任何经过它的顶点、边或属性
5.3.2.2. 没有任何返回结果
5.3.2.2.1. 发挥作用之后,它不会向客户端返回任何消息

6. 删除边

6.1. 方式1

6.1.1. 如果删除开始顶点或结束顶点,那么任何与该顶点关联的边也会被删除,这是图数据库版本的引用完整性体现

6.2. 方式2

6.2.1. 显式地删除它们,留下开始顶点和结束顶点

6.3. 过程

6.3.1. 给定一个遍历源g

6.3.2. 找到一条ID为15的边

6.3.3. 删除这条边

6.4. g.E(15).drop()

6.4.1. 在TinkerPop中,g.E()的默认实现需要一个类型为Long而不是int的参数,在Java中要留意这一点

6.4.2. 几乎和删除顶点的语句一模一样

6.4.2.1. 这种相似的语法也昭示了顶点和边在图数据库中同等重要

7. 修改图

7.1. UPDATE person SET first_name = 'Dave' WHERE first_name = 'Dav';

7.2. 过程

7.2.1. 给定一个遍历源g

7.2.2. 找到一个键为first_name、值为Dav的顶点

7.2.3. 修改该顶点的属性,将其值改为Dave

7.3. groovy

g.V().has('person', 'first_name', 'Dav').
      property('first_name', 'Dave')
==>v[18]

8. 脚本变异

8.1. groovy

g.V().drop().iterate()
dave = g.addV('person').property('first_name', 'Dave').next()
josh = g.addV('person').property('first_name', 'Josh').next()
ted = g.addV('person').property('first_name', 'Ted').next()
hank = g.addV('person').property('first_name', 'Hank').next()
g.addE('friends').from(dave).to(ted).next()
g.addE('friends').from(dave).to(josh).next()
g.addE('friends').from(dave).to(hank).next()
g.addE('friends').from(josh).to(hank).next()
g.addE('friends').from(ted).to(josh).next()

8.2. Gremlin代码的第一行是g.V().drop().iterate(),用来清除图中的所有数据

8.3. iterate()操作和next()操作类似,都会触发遍历

8.4. iterate()操作不会返回结果,而next()操作会返回遍历的结果

8.5. 由于drop()操作不返回值,因此这里使用iterate()操作比next()操作更合适

8.6. dave = g.addV('person').property('first_name', 'Dave').next()

8.6.1. 要在添加边之前把相应的顶点创建好

8.6.2. 过程

8.6.2.1. 给定一个遍历源g
8.6.2.2. 添加一个含有标签person的新顶点
8.6.2.3. 为这个顶点添加一个键为first_name、值为Dave的属性
8.6.2.4. 执行这些操作,返回迭代中的第一个(下一个)项作为结果

8.6.3. 声明保存遍历结果的变量dave

8.6.3.1. 变量是图世界中另一种差别的源头
8.6.3.1.1. Cypher,不支持这种跨请求的查询
8.6.3.1.2. 甚至在支持TinkerPop的图数据库间的支持程度都不一样
8.6.3.1.3. 不管是Azure的CosmosDB还是Amazon Nepture,都没有这个功能
8.6.3.1.4. JanusGraph和DataStax Enterprise Graph则完全支持
8.6.3.1.5. 如果查询语言和数据库支持变量的话,我们推荐使用它们
8.6.3.1.6. 变量可以极大地简化某些操作
8.6.3.1.6.1. 把添加顶点和边的操作串联在一起
8.6.3.2. 当要把结果赋值给一个变量时,则不得不包含终端操作
8.6.3.3. 否则,整个迭代集会被分配到变量中,而不只是迭代集里的那些结果
8.6.3.4. 这不是一个幂等的操作

8.6.4. next()

8.6.4.1. 一个终端操作,它从上一个操作获得迭代遍历源,迭代一次,然后返回迭代中的第一个或下一个项
8.6.4.2. 类似于iterate()的终端操作
8.6.4.3. 可以把它想成一个强制遍历循环的操作

8.7. g.addE('friends').from(dave).to(ted)

8.7.1. 给定一个遍历源g

8.7.2. 增加一条标签为friends的边

8.7.3. 出顶点指向dave变量

8.7.4. 入顶点指向ted变量

9. 链式变异

9.1. 在图数据库中,变异可以链接在一起,以同时执行多个变更

9.2. groovy

g.addE('friends').from(dave).to(josh).
  addE('friends').from(dave).to(hank).
  addE('friends').from(josh).to(hank).
  addE('friends').from(ted).to(josh).iterate()

9.3. 要在一个语句中包含复杂的操作,链接操作是Gremlin中的基本策略

9.3.1. 每一个操作从上一个操作的输出获取数据,并在处理后将该数据交给下一个操作

9.3.2. 对于熟悉函数式编程的朋友来说,这一切都似曾相识

9.4. 图遍历中的变异操作允许把多个变异操作链接成一个操作,而SQL做不到这一点

10. 路径(path)

10.1. 在遍历中从开始顶点访问到结束顶点之间的所有顶点和边的列表

10.2. 不仅告诉我们两个顶点是连接的,而且展示了它们之间的所有中间元素

10.3. 路径描述了从开始顶点到结束顶点的一系列遍历操作

10.4. 路径代表一系列连接两个元素的顶点和边

10.5. 意味着我们不仅能发现两个顶点是相互连接的,而且能确定如何从起点到达终点

10.6. groovy

g.V().has('person', 'first_name', 'Ted').
  until(has('person', 'first_name', 'Denise')).
  repeat(
    both('friends')
  ).path()

10.6.1. path()

10.6.1.1. 当遍历执行时,返回指定遍历器访问顶点(某些时候还有边)的历史
10.6.1.2. 在Gremlin中使用path()操作会增加服务器的资源消耗,因为每个遍历器都需要维护自己访问的所有历史记录
10.6.1.3. 只在需要所有路径数据时使用path()

10.7. groovy

Script evaluation exceeded the configured 'scriptEvaluationTimeout' threshold
     of 30000 ms or evaluation was otherwise cancelled directly for request
     [g.V().has('person', 'first_name', 'Ted').
  until(has('person', 'first_name', 'Denise')).
  repeat(
    both('friends')
  ).path()]
Type ':help' or ':h' for help.

10.7.1. 遍历超时了

10.7.2. 图中生成了一个环

10.7.2.1. 环是图论中的一个概念,指的是图中顶点和边的路径包含一个或多个能到达自己的顶点
10.7.2.2. 环指的是含有重复顶点的路径,通常会在图遍历过程中引起长时间运行的循环与寻路查询

10.7.3. :clear命令清除缓存并重新启动遍历

11. 简单路径

11.1. 不会在任何一个顶点上重复的路径

11.2. 在简单路径中只会得到非环的结果

11.2.1. 简单路径就是图中不含重复顶点的路径

11.3. 每个遍历器会维护它访问的所有项的历史

11.3.1. 当碰到一个曾经访问过的项时,它就知道这个元素在环中,并把它剔除

11.3.2. 只有那些不含环的遍历器会继续完成遍历工作

11.4. groovy

g.V().has('person', 'first_name', 'Ted').
  until(has('person', 'first_name', 'Denise')).
  repeat(
    both('friends').simplePath()
  ).path()
==>path[v[4], v[0], v[15], v[19]]
==>path[v[4], v[0], v[13], v[19]]
==>path[v[4], v[2], v[0], v[15], v[19]]
==>path[v[4], v[2], v[0], v[13], v[19]]
==>path[v[4], v[0], v[15], v[17], v[19]]
==>path[v[4], v[0], v[15], v[13], v[19]]
==>path[v[4], v[0], v[13], v[15], v[19]]
==>path[v[4], v[2], v[6], v[0], v[15], v[19]]
==>path[v[4], v[2], v[6], v[0], v[13], v[19]]
==>path[v[4], v[2], v[0], v[15], v[17], v[19]]
==>path[v[4], v[2], v[0], v[15], v[13], v[19]]
==>path[v[4], v[2], v[0], v[13], v[15], v[19]]
==>path[v[4], v[0], v[13], v[15], v[17], v[19]]
==>path[v[4], v[2], v[6], v[0], v[15], v[17], v[19]]
==>path[v[4], v[2], v[6], v[0], v[15], v[13], v[19]]
==>path[v[4], v[2], v[6], v[0], v[13], v[15], v[19]]
==>path[v[4], v[2], v[0], v[13], v[15], v[17], v[19]]
==>path[v[4], v[2], v[6], v[0], v[13], v[15], v[17], v[19]]

11.4.1. simplePath()

11.4.1.1. 筛选掉遍历中被重复访问的顶点
11.4.1.2. 如果把simplePath()放在遍历末尾,它就在循环逻辑之外了,遍历器会被困在环里,无法离开
11.4.1.3. 就像在Java里创建一个for循环,但把计数器变量放在for循环之外

12. 遍历和筛选边

12.1. 从顶点走到边,再从边走到顶点。必须显式遍历到边,并显式从边离开

12.2. 边可以直接被遍历和筛选,不需要遍历到相邻的顶点

12.3. InE(label)

12.3.1. 从当前顶点遍历到相邻的入边

12.4. outE(label)

12.4.1. 从当前顶点遍历到相邻的出边

12.5. bothE(label)

12.5.1. 从当前顶点遍历到相邻边,不考虑方向

12.6. 如果指定了标签,只遍历到符合筛选条件的边

12.7. 每个E操作都从一个顶点开始,遍历到一条边,然后停留在这条边上

12.7.1. 这些操作都结束于边,而不是相邻的顶点

12.8. inV()

12.8.1. 从当前边遍历到入顶点

12.8.2. 通常和outE()操作搭配使用

12.8.2.1. 组合来完成到相邻顶点的遍历

12.9. outV()

12.9.1. 从当前边遍历到出顶点

12.9.2. 通常和inE()操作搭配使用

12.9.2.1. 组合来完成到相邻顶点的遍历

12.10. otherV()

12.10.1. 遍历到不是出顶点的那个顶点(如另一个顶点)

12.10.2. 通常和bothE()操作搭配使用

12.10.2.1. 轻松地带到“另一个顶点”上,不是遍历出发的那个顶点

12.11. bothV()

12.11.1. 从当前边遍历到两个相邻的顶点

12.11.2. 极少用到

12.12. groovy

g.V().has('person','first_name','Dave').
  bothE('works_with').otherV().values('first_name')
==>Ted
==>Josh
==>Hank
==>Kelly
==>Denise

12.13. groovy

g.V().has('person', 'first_name','Dave').
  both('works_with').values('first_name')
==>Ted
==>Josh
==>Hank
==>Kelly
==>Denise

12.14. groovy

g.V().has('person', 'first_name', 'Ted').
  until(has('person', 'first_name', 'Denise')).
  repeat(
    bothE('works_with').otherV().simplePath()
  ).path()
==>path[v[4], e[29][0-works_with->4], v[0], e[33][0-works_with->19], v[19]]
==>path[v[4], e[29][0-works_with->4], v[0], e[32][0-works_with->13], v[13],
     e[34][19-works_with->13], v[19]]
==>path[v[4], e[30][2-works_with->4], v[2], e[28][0-works_with->2], v[0],
     e[33][0-works_with->19], v[19]]
==>path[v[4], e[30][2-works_with->4], v[2], e[28][0-works_with->2], v[0],
     e[[32][0-works_with->13], v[13], e[34][19-works_with->13], v[19]]

12.14.1. bothE().otherV()遍历模式来显式地遍历到边上

12.14.2. 在路径结果中包括边

12.14.3. 航空交通路线

12.14.3.1. 顶点代表机场,边代表机场间的航班

13. 通过属性筛选边

13.1. 基于时间的筛选

13.2. 基于权重的筛选

13.3. groovy

g.V().has('person','first_name','Dave').
  bothE('works_with').has('end_year',lte(2018)).
  otherV().
  values('first_name')
==>Josh
==>Ted
==>Hank

13.3.1. 可以基于边的属性进行筛选

13.3.2. 使用一些断言操作,如代表“小于或等于”的lte()

13.3.3. 对于比单值匹配更复杂的操作,断言操作是非常好用的管理工具

14. 边的计数

14.1. g.V().bothE().count()

14.2. g.V().both().count()

14.2.1. 通过both()操作来计数通常代价更高昂

15. 反规范化(denormalization)

15.1. 把经常访问的顶点属性复制到相邻的边上

15.2. 它对于某些以读为主的活动类型特别有帮助

15.3. 会带来维护同一个属性值的两份副本的开销

15.4. 维护数据的多个副本就是反规范化,不管使用关系数据库还是图数据库,反规范化都会带来这种额外的开销

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

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

相关文章

一篇博客理解Recyclerview的使用

从Android 5.0开始,谷歌公司推出了RecylerView控件,当看到RecylerView这个新控件的时候,大部分人会首先发出一个疑问,recylerview是什么?为什么会有recylerview也就是说recylerview的优点是什么?recylerview怎么用&…

图像视觉特效处理工具:Boris FX Optics 2024.0.1

BorisFX光效插件Optics首发2024版:3大新功能详解 2023年9月15日,全球领先的视觉后期软件开发公司BorisFX推出了旗下知名软件Boris FX Optics的全新2024版本,这款备受后期处理爱好者喜爱的Photoshop插件和独立程序再次升级,为您的…

【PC】特殊空投-2023年10月

亲爱的玩家朋友们,大家好! 10月特殊空投活动来袭。本月我们也准备了超多活动等着大家来体验。快来完成任务获得丰富的奖励吧!签到活动,每周一次的PUBG空投节,还有可以领取PGC2023免费投票劵的活动等着大家!…

聊聊统一认证中的四种安全认证协议(干货分享)

大家好,我是陈哈哈。单点登录SSO的出现是为了解决众多企业面临的痛点,场景即用户需要登录N个程序或系统,每个程序与系统都有不同的用户名和密码。在企业发展初期,可能仅仅有几个程序时,管理账户和密码不是一件难事。但…

软考系统架构师知识点集锦九:数据库系统

一、考情分析 二、考点精讲 2.1数据库概述 2.1.1数据库模式 (1)三级模式:外模式对应视图,模式(也称为概念模式)对应数据库表,内模式对应物理文件。(2)两层映像:外模式-模式映像,模式-内模式映像;两层映像可以保证数据库中的数据具有较高的…

linux查看系统版本、内核信息、操作系统类型版本

1. 使用 uname 命令:这将显示完整的内核版本信息,包括内核版本号、主机名、操作系统类型等。 uname -a2. 使用 lsb_release 命令(仅适用于支持 LSB(Linux Standard Base)的发行版):这将显示包含…

reactos 可调试光盘映像

链接:https://pan.baidu.com/s/13M9BZN4IDrWLc3bjnHO79g?pwd0gst 提取码:0gst

【计算机网络笔记】传输层——多路复用和多路分用

系列文章目录 什么是计算机网络? 什么是网络协议? 计算机网络的结构 数据交换之电路交换 数据交换之报文交换和分组交换 分组交换 vs 电路交换 计算机网络性能(1)——速率、带宽、延迟 计算机网络性能(2)…

08 _ 栈:如何实现浏览器的前进和后退功能?

浏览器的前进、后退功能,我想你肯定很熟悉吧? 当你依次访问完一串页面a-b-c之后,点击浏览器的后退按钮,就可以查看之前浏览过的页面b和a。当你后退到页面a,点击前进按钮,就可以重新查看页面b和c。但是,如果你后退到页面b后,点击了新的页面d,那就无法再通过前进、后退…

Qwt QwtScaleDraw自定义坐标轴

1.概述 QwtScaleDraw 是 Qt 绘图库 Qwt 中的一个类,用于绘制坐标轴刻度线和刻度标签。它提供了一些方法和属性来设置刻度线和标签的样式、布局和对齐方式。 以下是类继承关系: 2.常用方法 标签相关方法: setLabelRotation(double angle)&…

Hudi系列文章7-RFC24 Flink 写入流程优化

文章目录 前言问题背景瓶颈与解决方案瓶颈一解决方法工作流程:精准一次语义容灾CoorinatorCheckpoint如何配合使用StreamWriteOperatorCoordinator CheckpointedFunctionStreamWriteFunctionInstant 提前生成问题 瓶颈二问题解决方案BucketAssignerBucketWriter 重点…

将字符串中符合规则的元素替换为指定元素 re.sub()

【小白从小学Python、C、Java】 【计算机等级考试500强双证书】 【Python-数据分析】 将字符串中符合规则的元素 替换为指定元素 re.sub() 选择题 请问re.sub(r[0-9],*,s)的结果是: import re s "hello123" print("【显示】s ",s) print(&quo…

采购申请单明细账/汇总账页面编写

业务需求和功能 1、功能:编写采购申请页面和采购申请管理页面。在申请单界面添加常用的查询条件,如单品、申请单等。在采购申请管理页面以单品维度去展示采购申请单的汇总信息,添加一个默认查询时间为7天,并对查询出来的不同状态…

【设计模式三原则】

设计模式三原则 单一职责原则开放封闭原则依赖倒转原则里氏代换原则 我们在进行程序设计的时候,要尽可能地保证程序的可扩展性、可维护性和可读性,所以需要使用一些设计模式,这些设计模式都遵循了以下三个原则,下面来依次为大家介…

目标检测算法-SSD

1. SSD介绍 计算机确定图像中一个物体的位置需要四个参数:中心点的x轴、y轴坐标、框的高和宽。 当一张图片被传入SSD的网络中时,图片首先会被调整为300*300的大小。为了防止失真,其会在图片的边缘加上灰条。 之后SSD会将这种图片分为六种不…

IR2104/IR2184电机方案选择

供电越大Rdson越小 D3要用快恢复或者超快恢复不要用肖特基 上图有自举电容的取值公式,自举电容不能用电解电容,最好使用C0G因为它在不停的充放电 C31必须大于10倍C28

基于探路者算法的无人机航迹规划-附代码

基于探路者算法的无人机航迹规划 文章目录 基于探路者算法的无人机航迹规划1.探路者搜索算法2.无人机飞行环境建模3.无人机航迹规划建模4.实验结果4.1地图创建4.2 航迹规划 5.参考文献6.Matlab代码 摘要:本文主要介绍利用探路者算法来优化无人机航迹规划。 1.探路者…

LeetCode 2742.给墙壁刷油漆

思路 dp(u,count)为当前再考虑下标为1-u的墙面&#xff0c;并且还有count免费工次的最小代价 主要是递归边界的选择&#xff1a; u1<count return 0; if(u-1&&count<0)return 0x3f3f3f3f; if(u-1&&count0)retrun 0; 这三个可以合并成 if(u<count) …

k8s基本操作命令

目录 1、//查看资源对象简写 2、//查看集群信息 3、//配置kubectl自动补全 4、//node节点查看日志 5、//查看 master 节点状态 6、//查看命令空间 7、//查看default命名空间的所有资源 8、//创建命名空间app 9、//删除命名空间app 10、//在命名空间kube-public 创建…

量子计算与量子密码(入门级-少图版)

量子计算与量子密码 写在最前面一些可能带来的有趣的知识和潜在的收获 1、Introduction导言四个特性不确定性&#xff08;自由意志论&#xff09;Indeterminism不确定性Uncertainty叠加原理(线性)superposition (linearity)纠缠entanglement 虚数的常见基本运算欧拉公式&#x…