0
votes

My graph contains some "Person" nodes that "ContributedTo" some "Conversations" nodes. I want to write a Gremlin query that will create "TalksWith" edges directly between "Person" nodes. That edge should contain a property "countConversations" that shows how many conversations both these persons contributed to.

Is this possible doing using one Gremlin query for all "Person" nodes at once?

Here's my graph setup (using Gremlin console):

g = TinkerGraph.open().traversal()
g.addV("Person").as("p1").
addV("Person").as("p2").
addV("Person").as("p3").
addV("Person").as("p4").
addV("Person").as("p5").
addV("Conversation").as("c1").
addV("Conversation").as("c2").
addV("Conversation").as("c3").
addE("ContributedTo").from("p1").to("c1").
addE("ContributedTo").from("p2").to("c1").
addE("ContributedTo").from("p3").to("c1").
addE("ContributedTo").from("p1").to("c2").
addE("ContributedTo").from("p2").to("c2").
addE("ContributedTo").from("p3").to("c2").
addE("ContributedTo").from("p4").to("c2").
addE("ContributedTo").from("p5").to("c2").
addE("ContributedTo").from("p1").to("c3").
addE("ContributedTo").from("p3").to("c2")

What I want doing is creating "TalkedWith" edges like this

addE("TalkedWith").from("p1").to("p2").property("countConversations",2)

I wrote a query to count how many conversations a specific person had with other persons

g.V(0L).out("ContributedTo").in("ContributedTo")
.hasId(without(0L)).groupCount().order(local).by(values,desc).next()

Now I want to run this calculation for each person and create "TalksWith" edges.

1

1 Answers

1
votes

Here's one way to do it:

gremlin> g.V(0L).hasLabel('Person').
......1>   store('p').
......2>   out('ContributedTo').
......3>   in('ContributedTo').
......4>   where(without('p')).
......5>   groupCount().
......6>   unfold().
......7>   addE('TalkedWith').from(select('p').unfold()).to(select(keys)).
......8>     property('countConversations',select(values))
==>e[18][0-TalkedWith->1]
==>e[19][0-TalkedWith->2]
==>e[20][0-TalkedWith->3]
==>e[21][0-TalkedWith->4]
gremlin> g.E().hasLabel('TalkedWith').valueMap()
==>[countConversations:2]
==>[countConversations:3]
==>[countConversations:1]
==>[countConversations:1]

Given what you provided in your question as your progress in writing this traversal I'll assume you follow everything up to the groupCount() at line 5. At that point, we have a Map of the people v[0] talked to and the number of times they spoke. The next line deconstructs that Map into its component entries and iterates them creating an edge for each with addE(). The from vertex is gathered from "p" where it was original stored in a List and the to is extracted from the current key in the count map. The "countConversations" property then gets its value from current value of the count map.