深入学习Gremlin(18):随机过滤与注入

第18期 Gremlin Steps:

sample()coin()constant()inject()

本系列文章的Gremlin示例均在HugeGraph图数据库上执行,环境搭建可参考准备Gremlin执行环境,本文示例均以其中的“TinkerPop关系图”为初始数据。

tinkerpop关系图

上一期:深入学习Gremlin(17):待添加

随机过滤说明

Gremlin支持对遍历器(traversal)上的结果进行采样或者做随机过滤。

  • sample: 接受一个整数值,从前一步的遍历器中采样(随机)出最多指定数目的结果;
  • coin: 字面意思是抛硬币过滤,接受一个浮点值,该浮点值表示硬币出现正面的概率。coin Step 对前一步的遍历器中的每个元素都抛一次硬币,出现正面则可以通过,反面则被拦截。

sampleStep后能接上byStep,能以指定的属性为判断依据进行随机过滤。

注入说明

Gremlin允许在遍历器中注入一些默认值或自定义值,比如在分支 Step 中给 else 路径的元素一个默认值,又或者在遍历器过程中人为地加上一些额外的元素。

Inject Step
  • constant: 通常用在choosecoalesceStep中做辅助输出,为那些不满足条件的元素提供一个默认值;
  • inject: 能够在流(遍历器)的任何位置注入与当前遍历器同输出类型的对象,当然,也可以作为流的起始 Step 产生数据;

inject只是在查询过程中添加一些额外的元素,并没有把数据真正地插入到图中

实例讲解

下面通过实例来深入理解每一个操作。

  1. 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”

  1. 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

  2. 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'))
    
  3. 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')
    

下一期:深入学习Gremlin(19):待添加

你可能感兴趣的:(深入学习Gremlin(18):随机过滤与注入)