代码之家  ›  专栏  ›  技术社区  ›  A.Kostadinov

如何得到由满足特定条件的所有顶点组成的子图

  •  2
  • A.Kostadinov  · 技术社区  · 7 年前

    这个 是驻留在域逻辑特定层中的两个对象。

    这个 表示围绕您可以想到的任何材料的抽象。也就是说,每份合同、发票或图纸都可以称为 .

    修订 修订 文件 修订#2 相同的 .

    可能包含指向其他的链接 文件

    典型的 DAG

    Car elements - Documents and Revisions

    我设法使用 C# Graph API . 我设法遍历图表并执行简单的查询,以找到汽车有多少修订,或者发动机在最初创建时是否有涡轮增压器。

    截至2017年1月3日的汽车状况: Finished car

    截至2016年8月10日的汽车状况: Car's engine has no turbocharger yet

    1 回复  |  直到 7 年前
        1
  •  6
  •   stephen mallette    7 年前

    虽然图片很有帮助,但在询问有关Gremlin的问题时,始终提供一个可以生成图形样本的Gremlin脚本是很有帮助的。例如,对于您的问题:

    graph = TinkerGraph.open()
    g = graph.traversal()
    g.addV('car').property('name','car').as('car').
      addV('rev').property('name','car revision 1').property('date', 1470787200L).as('carV1').
      addV('rev').property('name','car revision 2').property('date', 1472688000L).as('carV2').
      addV('frontLeftDoor').property('name','front left door').as('frontLeftDoor').
      addV('frontRightDoor').property('name','front right door').as('frontRightDoor').
      addV('engine').property('name','engine').as('engine').
      addV('turbocharger').property('name','turbocharger').as('turbocharger').
      addV('rev').property('name','front left door revision 1').property('date',1470787200L).as('frontLeftDoorV1').
      addV('rev').property('name','front left door revision 2').property('date',1472688000L).as('frontLeftDoorV2').
      addV('rev').property('name','front right door revision 1').property('date',1470787200L).as('frontRightDoorV1').
      addV('rev').property('name','engine revision 1').property('date',1470787200L).as('engineV1').
      addV('rev').property('name','engine revision 2').property('date',1472688000L).as('engineV2'). 
      addV('rev').property('name','engine revision 3').property('date',1483401600L).as('engineV3').
      addV('rev').property('name','turbocharger revision 1').property('date',1470787200L).as('turbochargerV1'). 
      addV('rev').property('name','turbocharger revision 2').property('date',1472688000L).as('turbochargerV2'). 
      addE('relates').from('car').to('carV1').
      addE('relates').from('car').to('carV2').
      addE('relates').from('carV1').to('frontLeftDoor').
      addE('relates').from('carV1').to('frontRightDoor').
      addE('relates').from('carV1').to('engine').
      addE('relates').from('carV2').to('frontLeftDoor').
      addE('relates').from('carV2').to('frontRightDoor').
      addE('relates').from('carV2').to('engine').
      addE('relates').from('frontLeftDoor').to('frontLeftDoorV1').
      addE('relates').from('frontLeftDoor').to('frontLeftDoorV2').
      addE('relates').from('frontRightDoor').to('frontRightDoorV1').
      addE('relates').from('engine').to('engineV1').
      addE('relates').from('engine').to('engineV2').
      addE('relates').from('engine').to('engineV3').
      addE('relates').from('engineV2').to('turbocharger').
      addE('relates').from('engineV3').to('turbocharger').
      addE('relates').from('turbocharger').to('turbochargerV1').
      addE('relates').from('turbocharger').to('turbochargerV2').iterate()
    

    与开发提供答案的小精灵相比,回答问题的人通常需要更多的时间来创建问题的样本图。

    gremlin> g.V().has('name','car').
    ......1>   repeat(local(out().has('date',lte(1470787200L)).
    ......2>                order().
    ......3>                  by('date',decr).limit(1)).
    ......4>          out()).
    ......5>     emit().
    ......6>   local(out().has('date',lte(1470787200L)).
    ......7>         order().
    ......8>           by('date',decr).limit(1)).
    ......9>   tree().by('name')
    ==>[car:[car revision 1:[front right door:[front right door revision 1:[]],engine:[engine revision 1:[]],front left door:[front left door revision 1:[]]]]]
    

    以下是不同日期的相同穿越——“2017年1月1日”:

    gremlin> g.V().has('name','car').
    ......1>   repeat(local(out().has('date',lte(1483228800L)).
    ......2>                order().
    ......3>                  by('date',decr).limit(1)).
    ......4>          out()).
    ......5>     emit().
    ......6>   local(out().has('date',lte(1483228800L)).
    ......7>         order().
    ......8>           by('date',decr).limit(1)).
    ......9>   tree().by('name')
    ==>[car:[car revision 2:[front right door:[front right door revision 1:[]],engine:[engine revision 2:[turbocharger:[turbocharger revision 2:[]]]],front left door:[front left door revision 2:[]]]]]
    

    在这种情况下,请参见“engine revision 3”被排除在外,因为它是“2017年1月1日”之后的唯一顶点-树的其余部分存在。

    1. 为了便于比较,我将你的日期转换为long。我不确定CosmosDB是否能很好地处理关于 lte 的谓词 has() 但如果是这样的话,你可能更愿意走这条路。
    2. 这个 repeat() emit() 重复() 循环结束,因为没有更多 outE() 横穿。
    3. 重复()
    4. 我用过 tree() subgraph() 这一步在技术上甚至在Apache TinkerPop C#Gremlin语言变体中都不受支持——不幸的是,这其中存在一些挑战,使得Java只能提供功能。幸运的是,数据的形状是树状的 树()

    在Groovy中,可以通过闭包的方式提供重复的逻辑,以使事情更具可重用性:

    gremlin> traverseAndFilter = { out().has('date',lte(1470787200L)).
    ......1>                       order().
    ......2>                         by('date',decr).limit(1) }
    ==>groovysh_evaluate$_run_closure1@1d12e953
    gremlin> g.V().has('name','car').
    ......1>   repeat(local(traverseAndFilter()).out()).
    ......2>     emit().
    ......3>   local(local(traverseAndFilter())).
    ......4>   tree().by('name')
    ==>[car:[car revision 1:[front right door:[front right door revision 1:[]],engine:[engine revision 1:[]],front left door:[front left door revision 1:[]]]]]
    

    或者存储“traverseAndFilter”遍历本身,并 clone()

    gremlin> traverseAndFilter = out().has('date',lte(1470787200L)).
    ......1>                       order().
    ......2>                         by('date',decr).limit(1);[] 
    gremlin> g.V().has('name','car').
    ......1>   repeat(local(traverseAndFilter.clone()).out()).
    ......2>     emit().
    ......3>   local(local(traverseAndFilter.clone())).
    ......4>   tree().by('name')
    ==>[car:[car revision 1:[front right door:[front right door revision 1:[]],engine:[engine revision 1:[]],front left door:[front left door revision 1:[]]]]]