A.K*_*nov 2 gremlin tinkerpop3 gremlin-server azure-cosmosdb
的文献和修订是驻留在我们的域逻辑的特定层的两个对象.
该文件表示周围的任何材料一张纸,你能想到的抽象.也就是说 - 每份合同,发票或图纸都可以称为文件.
另一方面,文档的材料表示是修订:建筑工程师在现场接收的纸张列表表示设计者创建的文档的修订版.如果由于错误或需求更改而必须更改图形中的某些内容,则会在现场显示新修订 - 同一文档的修订版#2.
该版本可能包含指向其他文件 ; 因此,我们可以描述汽车,车门,发动机,车轮等之间的关系,以及每个元素独立演变的可能性,同时保持与其他元素的联系.
显示典型的DAG:
我设法使用C#Graph API将所有顶点和边插入到CosmosDB中.我设法遍历图表并执行简单查询,以便查找汽车有多少修改,或者发动机在最初创建时是否有涡轮增压器.但是,我正在努力编写一个复杂的查询,它只返回每个部分或汽车的最新版本,或者返回汽车状态的查询,直到2016-08-10.
当遍历访问顶点的后代(它的"out()")时,我找不到一种方法来获取最近创建的并继续遍历而不挖掘其他顶点.如果你建议我一个表达式,我只会从图片中返回彩色顶点,我将不胜感激.
虽然图片很有用,但在询问有关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()
Run Code Online (Sandbox Code Playgroud)
回答问题的人通常需要更多时间来为问题创建示例图,而不是开发提供答案的Gremlin.
无论如何,这是使用"8/10/2016"作为"开始日期"的一种方法:
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:[]]]]]
Run Code Online (Sandbox Code Playgroud)
这是与日期不同的遍历 - "1/1/2017":
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:[]]]]]
Run Code Online (Sandbox Code Playgroud)
在这种情况下,请注意"引擎版本3"被排除,因为它是"1/1/2017"之后的唯一顶点 - 树的其余部分存在.
几点说明:
lte
谓词的日期有很好的处理能力,has()
但如果确实如此,你可能更愿意选择那条路线.repeat()
步骤允许在树中进行任意深度遍历,但是请注意它之后包含的重复逻辑emit()
- 这会抓住最后的"树叶",repeat()
因为没有更多outE()
的遍历.repeat()
看起来有点复杂的逻辑,但它基本上只是说当前的"文档"遍历所有"修订",按日期降序排序并抓住第一个.一旦它具有由您关注的日期控制的最新版本,请遍历其连接的任何其他文档.tree()
在这种情况下使用了步骤,因为CosmosDB似乎支持这一点.它看起来并不像是支持它们subgraph()
.Apache TinkerPop C#Gremlin语言变体在技术上甚至不支持这一步骤 - 那里存在一些挑战,遗漏了Java唯一的功能.幸运的是,数据的形状是树状的,所以tree()
步骤似乎已经足够了.在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:[]]]]]
Run Code Online (Sandbox Code Playgroud)
或存储'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:[]]]]]
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
369 次 |
最近记录: |