第18期 Gremlin Steps:
sample()
、coin()
、constant()
、inject()
本系列文章的Gremlin示例均在HugeGraph图数据库上执行,环境搭建可参考准备Gremlin执行环境,本文示例均以其中的“TinkerPop关系图”为初始数据。
tinkerpop关系图随机过滤说明
Gremlin支持对遍历器(traversal)上的结果进行采样或者做随机过滤。
-
sample
: 接受一个整数值,从前一步的遍历器中采样(随机)出最多指定数目的结果; -
coin
: 字面意思是抛硬币过滤,接受一个浮点值,该浮点值表示硬币出现正面的概率。coin
Step 对前一步的遍历器中的每个元素都抛一次硬币,出现正面则可以通过,反面则被拦截。
sample
Step后能接上by
Step,能以指定的属性为判断依据进行随机过滤。
注入说明
Gremlin允许在遍历器中注入一些默认值或自定义值,比如在分支 Step 中给 else
路径的元素一个默认值,又或者在遍历器过程中人为地加上一些额外的元素。
-
constant
: 通常用在choose
或coalesce
Step中做辅助输出,为那些不满足条件的元素提供一个默认值; -
inject
: 能够在流(遍历器)的任何位置注入与当前遍历器同输出类型的对象,当然,也可以作为流的起始 Step 产生数据;
inject
只是在查询过程中添加一些额外的元素,并没有把数据真正地插入到图中
实例讲解
下面通过实例来深入理解每一个操作。
-
Step
sample()
示例1:
// 从所有顶点的出边中随机选择2条 g.V().outE().sample(2)
由于
sample
是随机采样,所以运行结果每次都可能不一样。另外,sample(n)
表示最多采样n
个,如果上一步不够n
个元素自然结果是会小于n
的。示例2:
// 从所以顶点的“name”属性中随机选取3个 g.V().values('name').sample(3)
示例3:
// 从所有的“person”中根据“age”随机选择3个 g.V().hasLabel('person').sample(3).by('age')
示例4:与
local
联合使用做随机漫游(从某个顶点出发,随机选一条边,走到边上的邻接点;再以该点为起点,继续随机选择边,走到邻接点...)// 从顶点“HugeGraph”出发做3次随机漫游 g.V('3:HugeGraph') .repeat(local(bothE().sample(1).otherV())) .times(3) .path()
第1次:从“HugeGraph”沿着“Szhoney>2>>S3:HugeGraph”走到“zhoney”
第2次:从“zhoney”沿着“Sjaveme>1>>Szhoney”走到“javeme”
第3次:从“javeme”沿着“Sjaveme>1>>Slinary”走到“linary”
-
Step
coin()
示例1:
// 每个顶点按0.5的概率过滤 g.V().coin(0.5)
这一次输出了5个顶点,而总共是有12个顶点的,为什么不是输出6个呢?学过概率论的应该都知道,不解释。我又多执行了两次,输出顶点数分别是5和7。
示例2:
// 每个顶点按0.0的概率过滤 g.V().coin(0.0)
示例3:
// 每个顶点按1.0的概率过滤 g.V().coin(1.0).count()
避免输出太长,加上
count
。 -
Step
constant()
示例1:
// 输出所有“person”类顶点的“name”属性,否则输出“inhuman”(非人类) g.V().choose(hasLabel('person'), values('name'), constant('inhuman'))
示例2:
// 与示例1功能相同,使用“coalesce”Step 实现 g.V().coalesce(hasLabel('person').values('name'), constant('inhuman'))
-
Step
inject()
示例1:
// 给顶点“HugeGraph”的作者添加一个叫“Tom”的人 g.V('3:HugeGraph').in('created').values('name').inject('Tom')
示例2:
// 在示例1的基础上计算每个元素的长度(“name”属性值的长度) g.V('3:HugeGraph').in('created').values('name').inject('Tom') .map {it.get().length()}
可以看到,注入的元素“Tom”与原生的元素一样参与了计算
示例3:
// 在示例2的基础上计算走过的路径 g.V('3:HugeGraph').in('created').values('name').inject('Tom') .map {it.get().length()}.path()
这里又能看出注入元素“Tom”与原生的元素的区别,由于“Tom”是在获取“name”属性这一步时才注入的,所以之前的从顶点“HugeGraph”出发,获取其“created”的入顶点这两步“Tom”是没有的。
示例4:
// 使用inject创建出两个元素(顶点的id),并使用该元素作为id获取顶点及其属性“name” inject('javeme', 'linary', 'zhoney').map {g.V(it.get()).next()}.values('name')
// 使用inject创建出一个“person”(顶点label),并使用该元素作为label获取顶点及其属性“name” inject('person').flatMap {g.V().hasLabel(it.get())}.values('name')
网友评论