有没有一种简单的方法来替换或合并顶点并保留/合并现有边?或者只是手动复制顶点的所有属性并重新创建现有的边和所有(元)属性,然后删除多余的顶点?
好吧,正如上面评论中提到的,您将在 OLTP 中进行匹配。这意味着您可能会有一个具体的切入点。让我们制作一个简单的示例图:
g = TinkerGraph.open().traversal()
// Stackoverflow data
g.addV("user").property("login", "user3508638").as("a").
addV("user").property("login", "dkuppitz").property("age", 35).as("b").
addV("question").property("title", "Tinkerpop/gremlin merge vertices (and edges)").as("c").
addE("posted").from("a").to("c").
addE("commented").from("b").to("c").property("time", 123).iterate()
// Github data
g.addV("user").property("login", "dkuppitz").property("name", "Daniel Kuppitz").as("a").
addV("project").property("title", "TinkerPop").as("b").
addE("contributed").from("a").to("b").iterate()
Run Code Online (Sandbox Code Playgroud)
要根据登录匹配顶点dkuppitz并将它们合并到单个用户顶点中:
g.V().has("login", "dkuppitz").
fold().filter(count(local).is(gt(1))).unfold().
sideEffect(properties().group("p").by(key).by(value())).
sideEffect(outE().group("o").by(label).by(project("p","iv").by(valueMap()).by(inV()).fold())).
sideEffect(inE().group("i").by(label).by(project("p","ov").by(valueMap()).by(outV()).fold())).
sideEffect(drop()).
cap("p","o","i").as("poi").
addV("user").as("u").
sideEffect(
select("poi").select("p").unfold().as("kv").
select("u").property(select("kv").select(keys), select("kv").select(values))).
sideEffect(
select("poi").select("o").unfold().as("x").
select("u").sideEffect { u ->
u.path("x").getValue().each { x ->
def e = u.get().addEdge(u.path("x").getKey(), x.get("iv"))
x.get("p").each { p ->
e.property(p.getKey(), p.getValue())
}
}
}).
sideEffect(
select("poi").select("i").unfold().as("x").
select("u").sideEffect { u ->
u.path("x").getValue().each { x ->
def e = x.get("ov").addEdge(u.path("x").getKey(), u.get())
x.get("p").each { p ->
e.property(p.getKey(), p.getValue())
}
}
}).iterate()
Run Code Online (Sandbox Code Playgroud)
我知道,查询非常复杂,尤其是深度嵌套的 lambda 表达式。但不幸的是,没有办法绕过 lambda,因为我们没有addE(<traversal>)重载(不过我创建了一张票)。无论如何,执行上面的查询后,图表如下所示:
gremlin> g.V().valueMap()
==>[login:[user3508638]]
==>[title:[Tinkerpop/gremlin merge vertices (and edges)]]
==>[title:[TinkerPop]]
==>[name:[Daniel Kuppitz],login:[dkuppitz],age:[35]]
gremlin> g.V().has("login", "dkuppitz").bothE()
==>e[19][15-commented->5]
==>e[20][15-contributed->12]
gremlin> g.V().has("login", "dkuppitz").bothE().valueMap(true)
==>[label:commented,time:123,id:19]
==>[label:contributed,id:20]
Run Code Online (Sandbox Code Playgroud)
两个dkuppitz顶点都合并为一个(name并且age存在属性),并且相应地重新创建了 2 条边。
更新:
使用TINKERPOP-1793我们可以摆脱所有 lambda:
g.V().has("login", "dkuppitz").
fold().filter(count(local).is(gt(1))).unfold().
sideEffect(properties().group("p").by(key).by(value())).
sideEffect(outE().group("o").by(label).by(project("p","iv").by(valueMap()).by(inV()).fold())).
sideEffect(inE().group("i").by(label).by(project("p","ov").by(valueMap()).by(outV()).fold())).
sideEffect(drop()).
cap("p","o","i").as("poi").
addV("user").as("u").
sideEffect(
select("poi").select("p").unfold().as("kv").
select("u").property(select("kv").select(keys), select("kv").select(values))).
sideEffect(
select("poi").select("o").unfold().as("x").select(values).
unfold().addE(select("x").select(keys)).from(select("u")).to(select("iv"))).
sideEffect(
select("poi").select("i").unfold().as("x").select(values).
unfold().addE(select("x").select(keys)).from(select("ov")).to(select("u"))).iterate()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2116 次 |
| 最近记录: |