Graph 用于从Cosmos图中获取受影响节点的Gremlin查询
我们有一个宇宙图数据库,如下所示。例如A、B、C,。。。是节点/顶点和边,如箭头所示 每个节点/顶点表示SQL表中的一个值。流程和要求如下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(
- D=A+B+C
- K=F+E+D
- M=J+K
- P=L+M+N+O
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]]
Igroup()
使用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]]