Find people who have the same song via more than 1 album

71 views
Skip to first unread message

er...@indexia.co

unread,
Jan 8, 2015, 10:08:37 AM1/8/15
to gremli...@googlegroups.com
Hello, 
I am trying to find paths between Person to Song, when the person Owns more than 1 album that Contains the song.

To clarify what I'm trying to do:

1. Person "Erez"  -- OWNS--> Album "Anthem of the Sun" --CONTAINS--> Song "Cryptical Envelopment"
2. Person "Erez"  -- OWNS--> Album "Anthem of the Sun" --CONTAINS--> Song "The Faster We Go, the Rounder We Get"
3. Person "Erez"  -- OWNS--> Album "Anthem of the Sun" --CONTAINS--> Song "We Leave the Castle"
4. Person "Erez"  -- OWNS--> Album "Anthem of the Sun Remixed" --CONTAINS--> Song "Cryptical Envelopment"

I'm trying to extract the paths:
         Erez, Anthem of the Sun, Cryptical Envelopment
         Erez, Anthem of the Sun Remixed, Cryptical Envelopment

I have tried:
1.  g.V('Person', 'Erez').sideEffect{x=it}.in('OWNS').in('CONTAINS').groupBy(m){x}{it}{it._().groupCount{it}.cap.next().findAll{s->s.value>1}}.   But I lost the context of the album.
2.  g.V('Person', 'Erez').in('OWNS').in('CONTAINS').path.groupBy(m){it[0]}{it[2]}{it._().groupCount{it}.cap.next().findAll{s->s.value>1}}.  Here I still have the context with the path, but I'm not sure how to filter or use it correctly. 

Thanks in advance.

Daniel Kuppitz

unread,
Jan 8, 2015, 11:21:02 AM1/8/15
to gremli...@googlegroups.com
Gremlin 2:

g = new TinkerGraph()
p = g.addVertex(["name": "Erez"])
a1 = g.addVertex(["name": "Anthem of the Sun"])
a2 = g.addVertex(["name": "Anthem of the Sun Remixed"])
s1 = g.addVertex(["name": "Cryptical Envelopment"])
s2 = g.addVertex(["name": "The Faster We Go, the Rounder We Get"])
s3 = g.addVertex(["name": "We Leave the Castle"])
p.addEdge("OWNS", a1)
p.addEdge("OWNS", a2)
a1.addEdge("CONTAINS", s1)
a1.addEdge("CONTAINS", s2)
a1.addEdge("CONTAINS", s3)
a2.addEdge("CONTAINS", s1)


gremlin> p.out("OWNS").out("CONTAINS").path() {it.name}.groupBy {[it[0], it[2]]} {it}.cap().next().grep { it.value.size() > 1 }*.value.collectMany {it}
==>[Erez, Anthem of the Sun, Cryptical Envelopment]
==>[Erez, Anthem of the Sun Remixed, Cryptical Envelopment]

Gremlin 3:

g = TinkerGraph.open()
p = g.addVertex("name", "Erez")
a1 = g.addVertex("name", "Anthem of the Sun")
a2 = g.addVertex("name", "Anthem of the Sun Remixed")
s1 = g.addVertex("name", "Cryptical Envelopment")
s2 = g.addVertex("name", "The Faster We Go, the Rounder We Get")
s3 = g.addVertex("name", "We Leave the Castle")
p.addEdge("OWNS", a1)
p.addEdge("OWNS", a2)
a1.addEdge("CONTAINS", s1)
a1.addEdge("CONTAINS", s2)
a1.addEdge("CONTAINS", s3)
a2.addEdge("CONTAINS", s1)


gremlin> p.out("OWNS").out("CONTAINS").path().by("name").group().by { [it.get(0), it.get(2)] }.next().grep { it.value.size() > 1 }*.value.flatten()
==>[Erez, Anthem of the Sun, Cryptical Envelopment]
==>[Erez, Anthem of the Sun Remixed, Cryptical Envelopment]

Cheers,
Daniel


--
You received this message because you are subscribed to the Google Groups "Gremlin-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to gremlin-user...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/gremlin-users/139603ec-2e7c-4c07-8697-5c277c0be8da%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Daniel Kuppitz

unread,
Jan 8, 2015, 2:23:52 PM1/8/15
to gremli...@googlegroups.com
Although it's already solved, I thought it might be interesting to see how the match-step can be used to solve the problem:

gremlin> g.V().has("name","Erez").match('a',
gremlin>     g.of().as('a').out("OWNS").as('b'),
gremlin>     g.of().as('a').out("OWNS").as('c'),
gremlin>     g.of().as('b').out("CONTAINS").as('d'),
gremlin>     g.of().as('c').out("CONTAINS").as('d')
gremlin> ).where('b', neq, 'c').select('a','c','d').by("name").dedup().map { it.get().values() }

==>[Erez, Anthem of the Sun, Cryptical Envelopment]
==>[Erez, Anthem of the Sun Remixed, Cryptical Envelopment]


Cheers,
Daniel

Daniel Kuppitz

unread,
Jan 8, 2015, 6:42:48 PM1/8/15
to gremli...@googlegroups.com
I've just had one more idea during dinner :)

gremlin> g.V().has("name","Erez").as("a").out("OWNS").as("b").out("CONTAINS").as("c").in("CONTAINS").except("b").in("OWNS").retain("a").select("a","b","c").by("name").dedup().map { it.get().values() }

==>[Erez, Anthem of the Sun, Cryptical Envelopment]
==>[Erez, Anthem of the Sun Remixed, Cryptical Envelopment]

My guess is, that this is the fastest of the 3 solutions.

Cheers,
Daniel

Jacek Laskowski

unread,
Jan 9, 2015, 9:43:52 AM1/9/15
to gremli...@googlegroups.com
Hi,

Awesome query! It's months until I'm gonna be able to write similar one myself. Thanks Daniel!

Hasn't g.of() just been replaced with __ (double '_')? Is the below query a simple s/g.of()/__?

Jacek

Daniel Kuppitz

unread,
Jan 9, 2015, 1:07:47 PM1/9/15
to gremli...@googlegroups.com
Hasn't g.of() just been replaced with __ (double '_')? Is the below query a simple s/g.of()/__?

Correct, the snapshot I was working with was a few days old, now it's __ instead of g.of().

Cheers,
Daniel


er...@indexia.co

unread,
Jan 11, 2015, 11:49:13 AM1/11/15
to gremli...@googlegroups.com
Hi and thanks for the help :)

We're currently using TinkerPop 2 so I ended up using the first solution.

Looking forward to working with TinkerPop 3.

Thanks, 
Erez.
Reply all
Reply to author
Forward
0 new messages