Can't make the pattern matching with a single gremlin statement

Showing 1-7 of 7 messages
Can't make the pattern matching with a single gremlin statement Prjio San 3/27/13 7:28 AM
I have a graph with dependencies:

    dep1 -> dep2 -> ... -> dep3 -> ...
        |                   ^
        +-> dep4            |
        |                   |
        +-------------------+

I'm looking for unnecessary dependencies, which are those where a direct link exists, but also a link through a sub-dependency. In the above example, the link "dep1 -> dep3" is unnecessary.

The cypher statement to find those would be:

    start n = node(*)
    match n -[:dependency]-> n2,
     n -[:dependency*2..]-> n2
     with n, n2
    return distinct id(n), n.name, id(n2), n2.name

I tried to solve this issue with a single gremlin statement (with the "table"-step), but I just couldn't make it work. Is this even possible or do I have to solve this with multiple statements?

Any hints, tips, ideas would be appreciated.

Thanks in advance
Re: [TinkerPop] Can't make the pattern matching with a single gremlin statement Marko A. Rodriguez 3/27/13 9:24 AM
Hi,

For a single vertex, lets say g.v(1), its:
x = [];
g.v(1).out('dependency').aggregate(x).out('dependency').loop(1){true}{true}.retain(x)

If you want this in a table-form, then do:

g.v(1).as('a').out('dependency').aggregate(x).out.loop(1){true}{true}.retain(x).as('b').select

With the select you can also provide closures to get whatever other metadata you want from the two emitted vertices.

Finally, if you want to do this for the whole graph, do:

g.V.transform {
x = []
it.as('a').out('dependency').aggregate(x).out('dependency').loop(1){true}{true}.retain(x).as('b').select
}

HTH,
Marko.


--
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.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Re: [TinkerPop] Can't make the pattern matching with a single gremlin statement Prjio San 3/28/13 8:09 AM
Hi Marko,

thanks for the reply, but unfortunately it doesn't work yet :(. I've created an example-graph (with yEd): https://gist.github.com/am-jo/b7e489dec05e88ff9a62
The edgeLabelKey is "d11":

g = new Neo4jGraph('/tmp/dependencies.db');
gr = new GraphMLReader(g);
gr.setEdgeLabelKey('d11');
gr.inputGraph(new FileInputStream('/tmp/gistfile1.xml'));

The expected result would be the dependency between foo(14) and bar(23).

Thanks for your time and effort.

PS: I tried to attach the file, but google just wouldn't let me upload it. That's why I'm posting the sample as gist.
Re: [TinkerPop] Can't make the pattern matching with a single gremlin statement Stephen Mallette 3/28/13 12:08 PM
I loaded your graphml into a tinkergraph and used Marko's gremlin with
just a few edits (all trivial):

gremlin> x=[];g.v("n13").as('a').out.aggregate(x).out.loop(1){true}{true}.retain(x).as('b').select{it.name}
==>[a:foo, b:bar]

His approach seems to find foo and bar which is what i understood you expected.

Stephen
Re: [TinkerPop] Can't make the pattern matching with a single gremlin statement Prjio San 3/28/13 12:57 PM
The single search works, but the search over the whole graph doesn't work yet. My apologies, for being unclear.
I receive a list of string representations of paths, after the transform.
Re: [TinkerPop] Can't make the pattern matching with a single gremlin statement Stephen Mallette 3/28/13 1:18 PM
You just need to iterate the pipe inside the transform:

gremlin> g.V.as('start').transform{s->x=[];s.as('a').out.aggregate(x).out.loop(1){true}{true}.retain(x).as('b').select{it.name}.toList()}.as('dependencies').select{it.name}{it}
==>[start:bob, dependencies:[]]
==>[start:a, dependencies:[]]
==>[start:a, dependencies:[]]
==>[start:bar, dependencies:[]]
==>[start:baz, dependencies:[]]
==>[start:a, dependencies:[]]
==>[start:a, dependencies:[]]
==>[start:a, dependencies:[]]
==>[start:bert, dependencies:[]]
==>[start:a, dependencies:[[a:a, b:ben]]]
==>[start:a, dependencies:[]]
==>[start:ben, dependencies:[]]
==>[start:a, dependencies:[]]
==>[start:a, dependencies:[]]
==>[start:mike, dependencies:[]]
==>[start:a, dependencies:[]]
==>[start:a, dependencies:[]]
==>[start:a, dependencies:[[a:a, b:a]]]
==>[start:a, dependencies:[[a:a, b:jim], [a:a, b:noodle], [a:a,
b:jim], [a:a, b:noodle], [a:a, b:jim], [a:a, b:foo], [a:a, b:a], [a:a,
b:noodle], [a:a, b:noodle], [a:a, b:jim], [a:a, b:jim]]]
==>[start:jim, dependencies:[]]
==>[start:foo, dependencies:[[a:foo, b:bar]]]
==>[start:a, dependencies:[]]
==>[start:noodle, dependencies:[[a:noodle, b:ben]]]
==>[start:a, dependencies:[]]

you may want to tweak that a bit depending on your result needs, but
note that I just added a toList() within the transform operation to
iterate the pipe.

Stephen
Re: [TinkerPop] Can't make the pattern matching with a single gremlin statement Prjio San 3/29/13 10:13 AM
Yes, this is pretty much it:

g.V.transform{
    s -> singleStep = [];
    s.as('origin')
        .out('dependency').aggregate(singleStep)
        .out('dependency')
            .loop(1){ true }{ true }
        .retain(singleStep).as('redundant')
        .dedup()
        .table(new Table(), ['origin', 'redundant']){ it.name + '(' + it.id + ')' }
        .cap().next()
}.filter{ it.size() > 0 }

Thanks a lot, guys.