gpt4 book ai didi

azure-cosmosdb - 如何获得由满足特定条件的所有顶点组成的子图

转载 作者:行者123 更新时间:2023-12-02 08:12:46 25 4
gpt4 key购买 nike

DocumentRevision 是驻留在我们领域逻辑特定层中的两个对象。

Document 表示围绕您能想到的任何 Material 纸的抽象。也就是说 - 每份契约(Contract)、发票或图纸都可以称为文件

另一方面,文档的 Material 表示是修订:建筑工程师在现场收到的文件 list 代表修订 设计者创建的文档。如果由于错误或更改要求而必须更改绘图中的某些内容,则新的修订版将出现在站点上 - Revision #2 是同一文档

修订 可能包含指向其他文档 的链接;因此,我们可以描述汽车、车门、发动机、车轮等之间的关系,以及每个元素独立进化的可能性,同时保持与其他元素的联系。

一个典型的DAG显示:

Car elements - Documents and Revisions

我设法使用 C# Graph API 将所有顶点和边插入到 CosmosDB 中.我设法遍历图表并执行简单的查询,以找出汽车有多少次修改,或者发动机在最初创建时是否有涡轮增压器。但是,我正在努力编写一个复杂的查询,该查询仅返回每个零件或汽车的最新修订版,或者返回 2016 年 8 月 10 日之前汽车状态的查询。

截至2017-01-03的汽车状态: Finished car

截至2016-08-10的汽车状态: Car's engine has no turbocharger yet

当遍历访问一个顶点(它的“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()

与开发提供答案的 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:[]]]]]

这是具有不同日期的相同遍历 - “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:[]]]]]

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

一些注意事项:

  1. 我将您的日期转换为多头以便于比较。我不确定 CosmosDB 是否可以很好地处理关于 has()lte 谓词的日期,但如果可以的话,您可能更愿意走那条路。<
  2. repeat() 步骤允许在树中进行任意深度遍历,但请注意它在 emit() 之后包含的重复逻辑 - 这捕获了repeat() 中的最终“树叶”循环结束,因为没有更多的 outE() 可以遍历。
  3. repeat() 里面的逻辑看起来有点复杂,但基本上就是说对当前的“文档”遍历所有的“修订版”,按日期降序排序并抓取第一个。一旦它具有由您关心的日期控制的最新版本,遍历它连接到的任何其他文档。
  4. 我在这种情况下使用了 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:[]]]]]

或存储“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:[]]]]]

关于azure-cosmosdb - 如何获得由满足特定条件的所有顶点组成的子图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44881401/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com