Graph 用于从Cosmos图中获取受影响节点的Gremlin查询

Graph 用于从Cosmos图中获取受影响节点的Gremlin查询,graph,azure-cosmosdb,gremlin,graph-databases,azure-cosmosdb-gremlinapi,Graph,Azure Cosmosdb,Gremlin,Graph Databases,Azure Cosmosdb Gremlinapi,我们有一个宇宙图数据库,如下所示。例如A、B、C,。。。是节点/顶点和边,如箭头所示 每个节点/顶点表示SQL表中的一个值。流程和要求如下 用户修改SQL表中的节点值 Gremlin查询将一个 Graph按下面列出的顺序返回以下顶点 C#app计算顺序中D、K、M、P节点的值,并更新SQL表 D=A+B+C K=F+E+D M=J+K P=L+M+N+O 我尝试了下面的查询,它有3000多个RU,这是非常昂贵的 g.V("A").emit().repeat(__.in(

我们有一个宇宙图数据库,如下所示。例如A、B、C,。。。是节点/顶点和边,如箭头所示

每个节点/顶点表示SQL表中的一个值。流程和要求如下

  • 用户修改SQL表中的节点值
  • Gremlin查询将一个
  • Graph按下面列出的顺序返回以下顶点
  • C#app计算顺序中D、K、M、P节点的值,并更新SQL表
    • D=A+B+C
    • K=F+E+D
    • M=J+K
    • P=L+M+N+O
    我尝试了下面的查询,它有3000多个RU,这是非常昂贵的

    g.V("A").emit().repeat(__.in('depends')).until(__.inE().count().is(0))
    
    我们需要一些帮助来优化查询。谢谢

    更新===========

    好的,我们可以在单个分区中重建图形以减少RU,但是我们有一个场景,其中多个节点受到影响,下图中以红色突出显示,从a开始

    有人能帮我查询一下以a、D、K、O、M、p的顺序得到结果吗?查询的逻辑是,所有子节点都应该在其父节点之前列出

    g.addV('ddn').property('pk', 'pk').property(id, 'A').property('formula', 'A').
    addV('ddn').property('pk', 'pk').property(id, 'B').property('formula', 'B').
    addV('ddn').property('pk', 'pk').property(id, 'C').property('formula', 'C').
    addV('ddn').property('pk', 'pk').property(id, 'D').property('formula', 'A+B+C').property('requires', "'A','B','C'").
    addV('ddn').property('pk', 'pk').property(id, 'E').property('formula', 'E').
    addV('ddn').property('pk', 'pk').property(id, 'F').property('formula', 'E').
    addV('ddn').property('pk', 'pk').property(id, 'G').property('formula', 'H+I').property('requires', "'H','I'").
    addV('ddn').property('pk', 'pk').property(id, 'H').property('formula', 'H').
    addV('ddn').property('pk', 'pk').property(id, 'I').property('formula', 'I').
    addV('ddn').property('pk', 'pk').property(id, 'J').property('formula', 'F+G').property('requires', "'F','G'").
    addV('ddn').property('pk', 'pk').property(id, 'K').property('formula', 'D+E+F').property('requires', "'D','E','F'").
    addV('ddn').property('pk', 'pk').property(id, 'L').property('formula', 'L').
    addV('ddn').property('pk', 'pk').property(id, 'M').property('formula', 'J+K').
    addV('ddn').property('pk', 'pk').property(id, 'N').property('formula', 'N').
    addV('ddn').property('pk', 'pk').property(id, 'O').property('formula', 'A+K').property('requires', "'A','K'").
    addV('ddn').property('pk', 'pk').property(id, 'P').property('formula', 'L+M+N+O').property('requires', "'L','M','N','O'").
    V('D').addE('needs').to(V('A')).
    V('D').addE('needs').to(V('B')).
    V('D').addE('needs').to(V('C')).
    V('G').addE('needs').to(V('H')).
    V('G').addE('needs').to(V('I')).
    V('K').addE('needs').to(V('D')).
    V('K').addE('needs').to(V('E')).
    V('K').addE('needs').to(V('F')).
    V('J').addE('needs').to(V('F')).
    V('J').addE('needs').to(V('G')).
    V('O').addE('needs').to(V('A')).
    V('O').addE('needs').to(V('K')).
    V('M').addE('needs').to(V('J')).
    V('M').addE('needs').to(V('K')).
    V('P').addE('needs').to(V('L')).
    V('P').addE('needs').to(V('M')).
    V('P').addE('needs').to(V('N')).
    V('P').addE('needs').to(V('O'))
    

    我认为答案归结为能够根据路径长度对穿过的顶点进行排序

    gremlin> g.V("A").
    ......1>   emit().repeat(__.in('needs')).path().
    ......2>   group().
    ......3>     by(tail(local)).
    ......4>     by(count(local).fold()).
    ......5>   order(local).
    ......6>     by(select(values).tail(local)).
    ......7>   select(keys)
    ==>[v[A],v[D],v[K],v[M],v[O],v[P]]
    
    I
    group()
    使用path()中的最后一个元素,并使用
    count(local)
    将组中的每个路径转换为其长度。这使我能够按每个顶点的最长路径对结果进行排序

    请注意,我认为您不需要
    ,直到(u.inE().count().is(0))
    ,因为在这两种情况下,您都只是遍历到路径耗尽。另外,请注意
    \uine().count().is(0)
    ,因为您最终只需对所有边进行计数即可检测到计数为零。大多数图都应该将其优化到只
    ,直到(inE())
    ,但在我看来,最好是显式的。这就是说,在使用
    repeat()
    时,您需要确保您的数据结构-只需要坏数据的一个边缘就可以将遍历发送到无限的遍历中。考虑一下你的<代码>重复()/代码>的上界,这对你的数据是有意义的,这样循环会在某个时刻终止。 这里有一个更好的选择,因为它不需要在
    组()之后保存
    映射中的所有计数:


    我假设A,D,K,m,P有不同的分区键?在这种情况下,不确定您能做多少,因为这将不可避免地在CosmosDB中生成一个跨分区查询,而这些查询总是expensive@AlexDreneaA,B,C,D…K,M,P是分区键。例如{pk='A',label='node'},{pk='B',label='node'}。是的,我想是的。。。“你的Gremlin查询看起来不错,我不确定除了重新访问数据模型以更好地适应这种查询模式之外,还有多少事情要做才能优化它,@AlexDrenea,”有什么建议吗?我们正在考虑使用带有不同标签的公共分区键创建单个热分区。即{pk='pk',label='A'},{pk='pk',label='B'}。你认为呢?热分区对于写操作来说是非常糟糕的(从时间上来说,不一定是这样)。尝试一下也没什么坏处,但要记住10GB的分区限制。有没有其他合乎逻辑的方法来对节点进行分组,使它们达到一个中间点?如果(A)的最后一个操作是跨分区的,那么您可以向数据库发出两个单独的调用,每个分区调用一个,然后在客户端上对它们进行汇总?谢谢。它给了我以下关于Azure Cosmos的错误<代码>"脚本评估错误:\r\n\nActivityId:7dc096a2-f3db-49a4-b053-F20F582CB66\nCeptionType:GraphRuntimeException\nCeptionMessage:\r\n\tGremlin查询执行错误:无法比较类型为:CompositeField的对象。\n源:Microsoft.Azure.Cosmos.Gremlin.Core\n\tGremlinRequestId:7dc096a2-f3db-49a4-b053-F20F582CB66\n\t上下文:graphcompute\n\t作用域:graphcomp execquery\n\tGraphInterOpStatusCode:GraphRuntimeError\n\tResult:0x80131500\r\n“
    工作到
    …by(count(local).fold())
    不超过
    order()
    Cosmodb似乎总有不兼容的地方。我在回答中提供了另一种选择
    gremlin> g.V("A").
    ......1>   emit().repeat(__.in('needs')).path().
    ......2>   group().
    ......3>     by(tail(local)).
    ......4>     by(count(local).order(local).tail(local)).
    ......5>   order(local).
    ......6>     by(values).
    ......7>   select(keys)
    ==>[v[A],v[D],v[K],v[M],v[O],v[P]]