我有一个看起来像这样的数据集:
V1 = name:"some name1"
V2 = name:"some name2"
V3 = name:"some name3"
V4 = name:"some name4"
E1 = weight:0.2, StartVertex:V1, EndVertex:V2
E2 = weight:0.3, StartVertex:V1, EndVertex:V3
E3 = weight:0.4, StartVertex:V1, EndVertex:V4
E4 = weight:0.5, StartVertex:V2, EndVertex:V1
E5 = weight:0.6, StartVertex:V2, EndVertex:V3
...
我有一个gremlin查询,可以找到这些顶点之间的一些路径。
我想在那里做两件事。
1:我希望能够找到所有重量的产品 path(path_edge1.weight * path_edge2.weight * ...)
2:我希望能够为每条路径求和产品 基于末端顶点。
我希望实现的伪代码:
g.V().has('name',REGEX,\".+some_query.+\").inE.outV.inE.FindingAPathSomehow.path{path_score = 1 : foreach edge e: path_score = path_score * e.weight}{it.lastV().id}.sumWhereIdIsEqual(it[1])
希望这有点可以理解。
我希望能够在纯粹的gremlin / groovy脚本中完成所有操作,因为我使用的是RexPro。
我已经看了很多答案,但还没找到办法做到这一点。
进一步解释如果上述内容不清楚:
查询时我正在寻找子串等于“some_query”的顶点。这将给我一组起始顶点。
使用这些顶点,我在我的图表中寻找一条特定的路径,它会给我几条路径,看起来像这样:
V = Vertex
E = Edge
Path1 = V3 - E2 - V1
Path2 = V4 - E5 - V7 - E1 - V1
这些边缘中的每一个都具有权重属性。有了这个,我想得到一个叫做"Big Pi" or "Capital Pi"的序列产品。想想求和(Σ)但用乘法代替加法。
Path1
的结果将是E2的权重,或上例中的0.3
。虽然Path2
的权重为E5.weight * E1.weight
,但上例中的0.6 * 0.2 = 0.12
将为V3
。
在这种情况下,我们从顶点V4
和V1
开始,两者都以Path1
结束。在这种情况下,我想总结Path2
和V1
的权重,因为两个终点都是V1
。这会将0.3 + 0.12 = 0.42
的总分作为Path3
。如果有V2
结尾顶点0.34
和得分{[V1, 0.42], [V2,0.34] }
,则结果列表中必须包含元素; {{1}}。
答案 0 :(得分:1)
您可以这样做:
gremlin> g = TinkerGraphFactory.createTinkerGraph()
==>tinkergraph[vertices:6 edges:6]
gremlin> g.v(1).as('s').outE.inV.loop('s'){it.loops<3}{true}.path
==>[v[1], e[7][1-knows->2], v[2]]
==>[v[1], e[8][1-knows->4], v[4]]
==>[v[1], e[9][1-created->3], v[3]]
==>[v[1], e[8][1-knows->4], v[4], e[10][4-created->5], v[5]]
==>[v[1], e[8][1-knows->4], v[4], e[11][4-created->3], v[3]]
以上使用玩具图获取一些路径,这些路径使用相同的端点产生多个结果。由于您要为每个路径乘以边缘权重,然后对每个以路径结束的顶点求和,所以看起来所有这些的良好返回值将Map
键入端点,其值为列表每条路径的权重列表。为此,我使用了groupBy
:
gremlin> m=g.v(1).as('s').outE.inV.loop('s'){it.loops<3}{true}.path.groupBy{it[it.size()-1]}{it.findAll{it instanceof Edge}.collect{it.getProperty("weight")}}.cap.next()
==>v[3]=[[0.4], [1.0, 0.4]]
==>v[2]=[[0.5]]
==>v[5]=[[1.0, 1.0]]
==>v[4]=[[1.0]]
groupBy
的第一个闭包提供了键(即路径中的最后一个顶点)。第二个闭包过滤Edge
个对象并拉出权重以存储在每个键的路径列表中。在此处,您可以使用m
或Map
进行操作以完成计算。在这一点上,我们基本上只是直接做Groovy。以下显示了权重乘积的计算:
gremlin> m.collect{k,v->[(k):v.collect{p->p.inject{product,weight->product*weight}}]}
==>{v[3]=[0.4, 0.4000000059604645]}
==>{v[2]=[0.5]}
==>{v[5]=[1.0]}
==>{v[4]=[1.0]}
一旦你有这么多,计算每个末端顶点的总和就是用groovy sum
函数完成的:
gremlin> m.collect{k,v->[(k):v.collect{p->p.inject{product,weight->product*weight}}.sum()]}
==>{v[3]=0.800000011920929}
==>{v[2]=0.5}
==>{v[5]=1.0}
==>{v[4]=1.0}
请注意,为了便于解释和阅读,我将其分解为多个Gremlin语句,但如果您喜欢单行样式,那么您也可以这样做。将其恢复为单行的最佳方法是向groupBy
添加第三个闭包,这将作为计算权重乘积/总和的减少步骤。