Warm tip: This article is reproduced from serverfault.com, please click

How to add multiple edges from one vertex in a single traversal

发布于 2020-12-01 05:01:19

I have three user vertices. Tom and Mike follow Bob.

g.addV("user").property(single,"name", "bob")
g.addV("user").property(single,"name", "tom")
g.addV("user").property(single,"name", "mike")
g.V().hasLabel("user").has("name", "tom").as("tom").V().hasLabel("user").has("name", "bob").addE("follow").from("tom")
g.V().hasLabel("user").has("name", "mike").as("mike").V().hasLabel("user").has("name", "bob").addE("follow").from("mike")

I'd like to add an alert with edges to the users. There should be an edge from Bob to the alert, and the alert should have edges out to the users that follow Bob.

g.V()
.hasLabel("user")
.has("name", "bob")
.as("bob")
.in("follow")
.as("followers")
.addV("alert")
.as("alert")
.addE("alert")
.from("alert")
.to("followers")
.addE("alert")
.from("bob")
.to("alert")

What I end up with is two alert vertices. Bob has an edge to each of these new alert vertices, and the alerts have edges out to Tom and Mike (the followers).

I believe this is because when I select the followers, it branches (?) the traversal and starts creating the duplicates but this is not what I want. How do I construct this traversal to make the appropriate selections but only create a single alert vertex? What I'm trying to get is this:

       bob
        |
        v
      alert
     |     |
     v     v
   mike   tom
Questioner
Fook
Viewed
0
stephen mallette 2020-12-01 19:48:51

You are correct that the duplicates come from the fact that in('follow') produces two traversers and thus addV('alert') gets called multiple times. There are many way you might resolve this, but here is the approach that came immediately to mind for me:

gremlin> g.V().
......1>   hasLabel("user").
......2>   has("name", "bob").as("b").
......3>   addV("alert").as('a').
......4>   addE("alerted").from("b").
......5>   select('b').
......6>   in("follow").
......7>   addE("alerted").from("a").iterate()
gremlin> g.V()
==>v[0]
==>v[2]
==>v[4]
==>v[8]
gremlin> g.V().elementMap()
==>[id:0,label:user,name:bob]
==>[id:2,label:user,name:tom]
==>[id:4,label:user,name:mike]
==>[id:8,label:alert]
gremlin> g.E().elementMap()
==>[id:6,label:follow,IN:[id:0,label:user],OUT:[id:2,label:user]]
==>[id:7,label:follow,IN:[id:0,label:user],OUT:[id:4,label:user]]
==>[id:9,label:alerted,IN:[id:8,label:alert],OUT:[id:0,label:user]]
==>[id:10,label:alerted,IN:[id:2,label:user],OUT:[id:8,label:alert]]
==>[id:11,label:alerted,IN:[id:4,label:user],OUT:[id:8,label:alert]]