You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tinkerpop.apache.org by David Bechberger <da...@bechberger.com> on 2021/02/04 22:17:31 UTC

[DISCUSS] Adding motif support to match()

Over the years of working with Gremlin I have foudn the match() step is
difficult to create traversals with and even more difficult to make it work
efficently.  While the imperative style of programming in Gremlin provides
a powerful path finding mechanism it really lacks an easy way to perform
pattern matching queries.  It would be great if we could simplify the
match() step to enable users to easily generate these pattern matching
traversals.

To accomplish this I was wondering what adding support for a subset of
motif/ascii art patterns to the match step might look like.  These types of
patterns are very easy for people to understand and I think the ability to
combine these pattern matching syntax with the powerful path finding and
formatting features of Gremlin would make a powerful combination.

To accomplish this I am suggesting supporting a subset of potential
patterns.  The two most common examples of this sort of pattern out there
are the openCypher type style and the style used by GraphX.  I have
provided a few examples below of what this syntax might look like:

e.g. openCypher style

Find me everything within one hop
g.V().match("()-[]->()")

Find me everything within one hop of a Person vertex
g.V().match("(p:Person)-[]->()")

Find me all Companies within one hop of a Person vertex
g.V().match("(p:Person)-[]->(c:Company)")

Find me all Companies within one hop of a Person vertex with an Employed_at
edge
g.V().match("(p:Person)-[e:employed_at]->(c:Company)")


The other option would be to take more of a hybrid approach and use only
the basic art/motifs like GraphX and apply the additional filtering in a
hybrid type of mode like this:

Find me all Companies within one hop of a Person vertex with an Employed_at
edge
g.V().match("(p)-[e]->(c)",
__.as('p').hasLabel('Person'),
__.as('e').hasLabel('employed_at'),
__.as('c').hasLabel('Company'),
)

This also has the potential to enable some significantly more complex
patterns like "Find me all Companies within one hop of a Person vertex with
an Employed_at edge who also worked at Foo"
g.V().match("(p)-[e]->(c)",
__.as('p').hasLabel('Person').out('employed_at').has('Company', 'name',
'Foo'),
__.as('e').hasLabel('employed_at'),
__.as('c').hasLabel('Company'),
)

Thoughts?

Dave

Re: [DISCUSS] Adding motif support to match()

Posted by Josh Perryman <jo...@gmail.com>.
Good point of clarification.

Though it is just a placeholder, starting with hasPattern() as the step
name and using the GraphX approach gives a solid bit of functionality out
of the gate. I like it as a next step on this path.

We can work on the step name, but hasPattern(), or maybe just pattern(),
does have a nice elegance to it.

Again, good call out on considering this approach separately from a
cypher() / openCypher() step. I would like to have this as well, but I
think a basic motif approach like above seems like a better next step.

-Josh



On Tue, Feb 9, 2021 at 11:46 AM David Bechberger <da...@bechberger.com>
wrote:

> Thanks for the great feedback.  In general, it seems like there is a lot of
> positive feedback on this idea and that it should be a separate from the
> existing match() step.
>
> I think there is one detail of my initial proposal that should probably be
> clarified.  In my initial proposal I wasn't thinking about adding the
> entirety of openCypher/Cypher syntax to Gremlin.  Instead, I was
> just thinking of adding the ASCII art portion of it.  If we only go with
> ASCII art portion, then I would be hesitant to use the cypher() step as
> that would potentially imply more functionality than available.
>
> It seems like there are a few questions we need to decide:
>
> * Do we want to support more than just ASCII Art from cypher/openCypher?
> * For the ASCII art do we want to take more of the approach of
> cypher/openCypher or the graphX approach to adding filtering:
> Examples (ignore the step name it's a placeholder)
>
> Question: Find me all Companies within one hop of a Person vertex with a
> name of Dave with an employed_at edge
>
> openCypher/Cypher syntax:
> g.V().hasPattern("(p:Person {name: 'Dave'})-[e:employed_at]->(c:Company)")
>
> GraphX style syntax:
>
> g.V().hasPattern("(p)-[e]->(c)",
> __.as('p').has('Person', 'name', 'Dave'),
> __.as('e').hasLabel('employed_at'),
> __.as('c').hasLabel('Company'),
> )
>
> Thoughts on these questions?
>
> Dave
>
> On Fri, Feb 5, 2021 at 4:36 AM Josh Perryman <jo...@gmail.com>
> wrote:
>
> > I do like the approach of formally including openCypher / ASCII art into
> > Gremlin / TinkerPop. I'm reluctant to overload the match() step for that
> > purpose.
> >
> > The match() step does have a similar purpose, but it has a fraught
> history.
> > I think it would work better from a number of angles to leave it as it
> is.
> >
> > I'm more aligned with Joshua's recommendation. The use of the cypher()
> > step  (or perhaps an openCypher() step?) makes explicit the transition to
> > another language and processing approach.  This pairs nicely with the
> > sparql() step and provides an intuitive pattern to introduce other data
> > querying approaches ( sql(), gql(), prolog(), mmADT(), pigeon(), ... ).
> >
> > I do rather like the idea of the overloads within the step, ways to
> "hook"
> > the Gremlin into whatever the query language is. That could provide
> > remarkable flexibility and opens up a whole suite of capabilities.
> >
> > Overall, this is a really great idea which should help with
> > interoperability between TinkerPop and other graph frameworks.
> >
> > Josh
> >
> >
> > On Thu, Feb 4, 2021 at 10:30 PM pieter gmail <pi...@gmail.com>
> > wrote:
> >
> > > +1
> > >
> > > Cheers
> > > Pieter
> > >
> > > On Thu, 2021-02-04 at 17:15 -0800, Joshua Shinavier wrote:
> > > > Initial thought: if the ASCII art syntax is Cypher-like, why not make
> > > > it
> > > > openCypher proper? I.e. keep match() as it is, but generalize the
> > > > cypher()
> > > > step out of Neo4jGraph, with native Neo4j evaluation of Cypher as an
> > > > optimization.
> > > >
> > > > Josh
> > > >
> > > >
> > > > On Thu, Feb 4, 2021 at 2:17 PM David Bechberger <dave@bechberger.com
> >
> > > > wrote:
> > > >
> > > > > Over the years of working with Gremlin I have foudn the match()
> > > > > step is
> > > > > difficult to create traversals with and even more difficult to make
> > > > > it work
> > > > > efficently.  While the imperative style of programming in Gremlin
> > > > > provides
> > > > > a powerful path finding mechanism it really lacks an easy way to
> > > > > perform
> > > > > pattern matching queries.  It would be great if we could simplify
> > > > > the
> > > > > match() step to enable users to easily generate these pattern
> > > > > matching
> > > > > traversals.
> > > > >
> > > > > To accomplish this I was wondering what adding support for a subset
> > > > > of
> > > > > motif/ascii art patterns to the match step might look like.  These
> > > > > types of
> > > > > patterns are very easy for people to understand and I think the
> > > > > ability to
> > > > > combine these pattern matching syntax with the powerful path
> > > > > finding and
> > > > > formatting features of Gremlin would make a powerful combination.
> > > > >
> > > > > To accomplish this I am suggesting supporting a subset of potential
> > > > > patterns.  The two most common examples of this sort of pattern out
> > > > > there
> > > > > are the openCypher type style and the style used by GraphX.  I have
> > > > > provided a few examples below of what this syntax might look like:
> > > > >
> > > > > e.g. openCypher style
> > > > >
> > > > > Find me everything within one hop
> > > > > g.V().match("()-[]->()")
> > > > >
> > > > > Find me everything within one hop of a Person vertex
> > > > > g.V().match("(p:Person)-[]->()")
> > > > >
> > > > > Find me all Companies within one hop of a Person vertex
> > > > > g.V().match("(p:Person)-[]->(c:Company)")
> > > > >
> > > > > Find me all Companies within one hop of a Person vertex with an
> > > > > Employed_at
> > > > > edge
> > > > > g.V().match("(p:Person)-[e:employed_at]->(c:Company)")
> > > > >
> > > > >
> > > > > The other option would be to take more of a hybrid approach and use
> > > > > only
> > > > > the basic art/motifs like GraphX and apply the additional filtering
> > > > > in a
> > > > > hybrid type of mode like this:
> > > > >
> > > > > Find me all Companies within one hop of a Person vertex with an
> > > > > Employed_at
> > > > > edge
> > > > > g.V().match("(p)-[e]->(c)",
> > > > > __.as('p').hasLabel('Person'),
> > > > > __.as('e').hasLabel('employed_at'),
> > > > > __.as('c').hasLabel('Company'),
> > > > > )
> > > > >
> > > > > This also has the potential to enable some significantly more
> > > > > complex
> > > > > patterns like "Find me all Companies within one hop of a Person
> > > > > vertex with
> > > > > an Employed_at edge who also worked at Foo"
> > > > > g.V().match("(p)-[e]->(c)",
> > > > > __.as('p').hasLabel('Person').out('employed_at').has('Company',
> > > > > 'name',
> > > > > 'Foo'),
> > > > > __.as('e').hasLabel('employed_at'),
> > > > > __.as('c').hasLabel('Company'),
> > > > > )
> > > > >
> > > > > Thoughts?
> > > > >
> > > > > Dave
> > > > >
> > >
> > >
> >
>

Re: [DISCUSS] Adding motif support to match()

Posted by David Bechberger <da...@bechberger.com>.
Thanks for the great feedback.  In general, it seems like there is a lot of
positive feedback on this idea and that it should be a separate from the
existing match() step.

I think there is one detail of my initial proposal that should probably be
clarified.  In my initial proposal I wasn't thinking about adding the
entirety of openCypher/Cypher syntax to Gremlin.  Instead, I was
just thinking of adding the ASCII art portion of it.  If we only go with
ASCII art portion, then I would be hesitant to use the cypher() step as
that would potentially imply more functionality than available.

It seems like there are a few questions we need to decide:

* Do we want to support more than just ASCII Art from cypher/openCypher?
* For the ASCII art do we want to take more of the approach of
cypher/openCypher or the graphX approach to adding filtering:
Examples (ignore the step name it's a placeholder)

Question: Find me all Companies within one hop of a Person vertex with a
name of Dave with an employed_at edge

openCypher/Cypher syntax:
g.V().hasPattern("(p:Person {name: 'Dave'})-[e:employed_at]->(c:Company)")

GraphX style syntax:

g.V().hasPattern("(p)-[e]->(c)",
__.as('p').has('Person', 'name', 'Dave'),
__.as('e').hasLabel('employed_at'),
__.as('c').hasLabel('Company'),
)

Thoughts on these questions?

Dave

On Fri, Feb 5, 2021 at 4:36 AM Josh Perryman <jo...@gmail.com> wrote:

> I do like the approach of formally including openCypher / ASCII art into
> Gremlin / TinkerPop. I'm reluctant to overload the match() step for that
> purpose.
>
> The match() step does have a similar purpose, but it has a fraught history.
> I think it would work better from a number of angles to leave it as it is.
>
> I'm more aligned with Joshua's recommendation. The use of the cypher()
> step  (or perhaps an openCypher() step?) makes explicit the transition to
> another language and processing approach.  This pairs nicely with the
> sparql() step and provides an intuitive pattern to introduce other data
> querying approaches ( sql(), gql(), prolog(), mmADT(), pigeon(), ... ).
>
> I do rather like the idea of the overloads within the step, ways to "hook"
> the Gremlin into whatever the query language is. That could provide
> remarkable flexibility and opens up a whole suite of capabilities.
>
> Overall, this is a really great idea which should help with
> interoperability between TinkerPop and other graph frameworks.
>
> Josh
>
>
> On Thu, Feb 4, 2021 at 10:30 PM pieter gmail <pi...@gmail.com>
> wrote:
>
> > +1
> >
> > Cheers
> > Pieter
> >
> > On Thu, 2021-02-04 at 17:15 -0800, Joshua Shinavier wrote:
> > > Initial thought: if the ASCII art syntax is Cypher-like, why not make
> > > it
> > > openCypher proper? I.e. keep match() as it is, but generalize the
> > > cypher()
> > > step out of Neo4jGraph, with native Neo4j evaluation of Cypher as an
> > > optimization.
> > >
> > > Josh
> > >
> > >
> > > On Thu, Feb 4, 2021 at 2:17 PM David Bechberger <da...@bechberger.com>
> > > wrote:
> > >
> > > > Over the years of working with Gremlin I have foudn the match()
> > > > step is
> > > > difficult to create traversals with and even more difficult to make
> > > > it work
> > > > efficently.  While the imperative style of programming in Gremlin
> > > > provides
> > > > a powerful path finding mechanism it really lacks an easy way to
> > > > perform
> > > > pattern matching queries.  It would be great if we could simplify
> > > > the
> > > > match() step to enable users to easily generate these pattern
> > > > matching
> > > > traversals.
> > > >
> > > > To accomplish this I was wondering what adding support for a subset
> > > > of
> > > > motif/ascii art patterns to the match step might look like.  These
> > > > types of
> > > > patterns are very easy for people to understand and I think the
> > > > ability to
> > > > combine these pattern matching syntax with the powerful path
> > > > finding and
> > > > formatting features of Gremlin would make a powerful combination.
> > > >
> > > > To accomplish this I am suggesting supporting a subset of potential
> > > > patterns.  The two most common examples of this sort of pattern out
> > > > there
> > > > are the openCypher type style and the style used by GraphX.  I have
> > > > provided a few examples below of what this syntax might look like:
> > > >
> > > > e.g. openCypher style
> > > >
> > > > Find me everything within one hop
> > > > g.V().match("()-[]->()")
> > > >
> > > > Find me everything within one hop of a Person vertex
> > > > g.V().match("(p:Person)-[]->()")
> > > >
> > > > Find me all Companies within one hop of a Person vertex
> > > > g.V().match("(p:Person)-[]->(c:Company)")
> > > >
> > > > Find me all Companies within one hop of a Person vertex with an
> > > > Employed_at
> > > > edge
> > > > g.V().match("(p:Person)-[e:employed_at]->(c:Company)")
> > > >
> > > >
> > > > The other option would be to take more of a hybrid approach and use
> > > > only
> > > > the basic art/motifs like GraphX and apply the additional filtering
> > > > in a
> > > > hybrid type of mode like this:
> > > >
> > > > Find me all Companies within one hop of a Person vertex with an
> > > > Employed_at
> > > > edge
> > > > g.V().match("(p)-[e]->(c)",
> > > > __.as('p').hasLabel('Person'),
> > > > __.as('e').hasLabel('employed_at'),
> > > > __.as('c').hasLabel('Company'),
> > > > )
> > > >
> > > > This also has the potential to enable some significantly more
> > > > complex
> > > > patterns like "Find me all Companies within one hop of a Person
> > > > vertex with
> > > > an Employed_at edge who also worked at Foo"
> > > > g.V().match("(p)-[e]->(c)",
> > > > __.as('p').hasLabel('Person').out('employed_at').has('Company',
> > > > 'name',
> > > > 'Foo'),
> > > > __.as('e').hasLabel('employed_at'),
> > > > __.as('c').hasLabel('Company'),
> > > > )
> > > >
> > > > Thoughts?
> > > >
> > > > Dave
> > > >
> >
> >
>

Re: [DISCUSS] Adding motif support to match()

Posted by Josh Perryman <jo...@gmail.com>.
I do like the approach of formally including openCypher / ASCII art into
Gremlin / TinkerPop. I'm reluctant to overload the match() step for that
purpose.

The match() step does have a similar purpose, but it has a fraught history.
I think it would work better from a number of angles to leave it as it is.

I'm more aligned with Joshua's recommendation. The use of the cypher()
step  (or perhaps an openCypher() step?) makes explicit the transition to
another language and processing approach.  This pairs nicely with the
sparql() step and provides an intuitive pattern to introduce other data
querying approaches ( sql(), gql(), prolog(), mmADT(), pigeon(), ... ).

I do rather like the idea of the overloads within the step, ways to "hook"
the Gremlin into whatever the query language is. That could provide
remarkable flexibility and opens up a whole suite of capabilities.

Overall, this is a really great idea which should help with
interoperability between TinkerPop and other graph frameworks.

Josh


On Thu, Feb 4, 2021 at 10:30 PM pieter gmail <pi...@gmail.com>
wrote:

> +1
>
> Cheers
> Pieter
>
> On Thu, 2021-02-04 at 17:15 -0800, Joshua Shinavier wrote:
> > Initial thought: if the ASCII art syntax is Cypher-like, why not make
> > it
> > openCypher proper? I.e. keep match() as it is, but generalize the
> > cypher()
> > step out of Neo4jGraph, with native Neo4j evaluation of Cypher as an
> > optimization.
> >
> > Josh
> >
> >
> > On Thu, Feb 4, 2021 at 2:17 PM David Bechberger <da...@bechberger.com>
> > wrote:
> >
> > > Over the years of working with Gremlin I have foudn the match()
> > > step is
> > > difficult to create traversals with and even more difficult to make
> > > it work
> > > efficently.  While the imperative style of programming in Gremlin
> > > provides
> > > a powerful path finding mechanism it really lacks an easy way to
> > > perform
> > > pattern matching queries.  It would be great if we could simplify
> > > the
> > > match() step to enable users to easily generate these pattern
> > > matching
> > > traversals.
> > >
> > > To accomplish this I was wondering what adding support for a subset
> > > of
> > > motif/ascii art patterns to the match step might look like.  These
> > > types of
> > > patterns are very easy for people to understand and I think the
> > > ability to
> > > combine these pattern matching syntax with the powerful path
> > > finding and
> > > formatting features of Gremlin would make a powerful combination.
> > >
> > > To accomplish this I am suggesting supporting a subset of potential
> > > patterns.  The two most common examples of this sort of pattern out
> > > there
> > > are the openCypher type style and the style used by GraphX.  I have
> > > provided a few examples below of what this syntax might look like:
> > >
> > > e.g. openCypher style
> > >
> > > Find me everything within one hop
> > > g.V().match("()-[]->()")
> > >
> > > Find me everything within one hop of a Person vertex
> > > g.V().match("(p:Person)-[]->()")
> > >
> > > Find me all Companies within one hop of a Person vertex
> > > g.V().match("(p:Person)-[]->(c:Company)")
> > >
> > > Find me all Companies within one hop of a Person vertex with an
> > > Employed_at
> > > edge
> > > g.V().match("(p:Person)-[e:employed_at]->(c:Company)")
> > >
> > >
> > > The other option would be to take more of a hybrid approach and use
> > > only
> > > the basic art/motifs like GraphX and apply the additional filtering
> > > in a
> > > hybrid type of mode like this:
> > >
> > > Find me all Companies within one hop of a Person vertex with an
> > > Employed_at
> > > edge
> > > g.V().match("(p)-[e]->(c)",
> > > __.as('p').hasLabel('Person'),
> > > __.as('e').hasLabel('employed_at'),
> > > __.as('c').hasLabel('Company'),
> > > )
> > >
> > > This also has the potential to enable some significantly more
> > > complex
> > > patterns like "Find me all Companies within one hop of a Person
> > > vertex with
> > > an Employed_at edge who also worked at Foo"
> > > g.V().match("(p)-[e]->(c)",
> > > __.as('p').hasLabel('Person').out('employed_at').has('Company',
> > > 'name',
> > > 'Foo'),
> > > __.as('e').hasLabel('employed_at'),
> > > __.as('c').hasLabel('Company'),
> > > )
> > >
> > > Thoughts?
> > >
> > > Dave
> > >
>
>

Re: [DISCUSS] Adding motif support to match()

Posted by pieter gmail <pi...@gmail.com>.
+1

Cheers
Pieter

On Thu, 2021-02-04 at 17:15 -0800, Joshua Shinavier wrote:
> Initial thought: if the ASCII art syntax is Cypher-like, why not make
> it
> openCypher proper? I.e. keep match() as it is, but generalize the
> cypher()
> step out of Neo4jGraph, with native Neo4j evaluation of Cypher as an
> optimization.
> 
> Josh
> 
> 
> On Thu, Feb 4, 2021 at 2:17 PM David Bechberger <da...@bechberger.com>
> wrote:
> 
> > Over the years of working with Gremlin I have foudn the match()
> > step is
> > difficult to create traversals with and even more difficult to make
> > it work
> > efficently.  While the imperative style of programming in Gremlin
> > provides
> > a powerful path finding mechanism it really lacks an easy way to
> > perform
> > pattern matching queries.  It would be great if we could simplify
> > the
> > match() step to enable users to easily generate these pattern
> > matching
> > traversals.
> > 
> > To accomplish this I was wondering what adding support for a subset
> > of
> > motif/ascii art patterns to the match step might look like.  These
> > types of
> > patterns are very easy for people to understand and I think the
> > ability to
> > combine these pattern matching syntax with the powerful path
> > finding and
> > formatting features of Gremlin would make a powerful combination.
> > 
> > To accomplish this I am suggesting supporting a subset of potential
> > patterns.  The two most common examples of this sort of pattern out
> > there
> > are the openCypher type style and the style used by GraphX.  I have
> > provided a few examples below of what this syntax might look like:
> > 
> > e.g. openCypher style
> > 
> > Find me everything within one hop
> > g.V().match("()-[]->()")
> > 
> > Find me everything within one hop of a Person vertex
> > g.V().match("(p:Person)-[]->()")
> > 
> > Find me all Companies within one hop of a Person vertex
> > g.V().match("(p:Person)-[]->(c:Company)")
> > 
> > Find me all Companies within one hop of a Person vertex with an
> > Employed_at
> > edge
> > g.V().match("(p:Person)-[e:employed_at]->(c:Company)")
> > 
> > 
> > The other option would be to take more of a hybrid approach and use
> > only
> > the basic art/motifs like GraphX and apply the additional filtering
> > in a
> > hybrid type of mode like this:
> > 
> > Find me all Companies within one hop of a Person vertex with an
> > Employed_at
> > edge
> > g.V().match("(p)-[e]->(c)",
> > __.as('p').hasLabel('Person'),
> > __.as('e').hasLabel('employed_at'),
> > __.as('c').hasLabel('Company'),
> > )
> > 
> > This also has the potential to enable some significantly more
> > complex
> > patterns like "Find me all Companies within one hop of a Person
> > vertex with
> > an Employed_at edge who also worked at Foo"
> > g.V().match("(p)-[e]->(c)",
> > __.as('p').hasLabel('Person').out('employed_at').has('Company',
> > 'name',
> > 'Foo'),
> > __.as('e').hasLabel('employed_at'),
> > __.as('c').hasLabel('Company'),
> > )
> > 
> > Thoughts?
> > 
> > Dave
> > 


Re: [DISCUSS] Adding motif support to match()

Posted by Joshua Shinavier <jo...@fortytwo.net>.
Initial thought: if the ASCII art syntax is Cypher-like, why not make it
openCypher proper? I.e. keep match() as it is, but generalize the cypher()
step out of Neo4jGraph, with native Neo4j evaluation of Cypher as an
optimization.

Josh


On Thu, Feb 4, 2021 at 2:17 PM David Bechberger <da...@bechberger.com> wrote:

> Over the years of working with Gremlin I have foudn the match() step is
> difficult to create traversals with and even more difficult to make it work
> efficently.  While the imperative style of programming in Gremlin provides
> a powerful path finding mechanism it really lacks an easy way to perform
> pattern matching queries.  It would be great if we could simplify the
> match() step to enable users to easily generate these pattern matching
> traversals.
>
> To accomplish this I was wondering what adding support for a subset of
> motif/ascii art patterns to the match step might look like.  These types of
> patterns are very easy for people to understand and I think the ability to
> combine these pattern matching syntax with the powerful path finding and
> formatting features of Gremlin would make a powerful combination.
>
> To accomplish this I am suggesting supporting a subset of potential
> patterns.  The two most common examples of this sort of pattern out there
> are the openCypher type style and the style used by GraphX.  I have
> provided a few examples below of what this syntax might look like:
>
> e.g. openCypher style
>
> Find me everything within one hop
> g.V().match("()-[]->()")
>
> Find me everything within one hop of a Person vertex
> g.V().match("(p:Person)-[]->()")
>
> Find me all Companies within one hop of a Person vertex
> g.V().match("(p:Person)-[]->(c:Company)")
>
> Find me all Companies within one hop of a Person vertex with an Employed_at
> edge
> g.V().match("(p:Person)-[e:employed_at]->(c:Company)")
>
>
> The other option would be to take more of a hybrid approach and use only
> the basic art/motifs like GraphX and apply the additional filtering in a
> hybrid type of mode like this:
>
> Find me all Companies within one hop of a Person vertex with an Employed_at
> edge
> g.V().match("(p)-[e]->(c)",
> __.as('p').hasLabel('Person'),
> __.as('e').hasLabel('employed_at'),
> __.as('c').hasLabel('Company'),
> )
>
> This also has the potential to enable some significantly more complex
> patterns like "Find me all Companies within one hop of a Person vertex with
> an Employed_at edge who also worked at Foo"
> g.V().match("(p)-[e]->(c)",
> __.as('p').hasLabel('Person').out('employed_at').has('Company', 'name',
> 'Foo'),
> __.as('e').hasLabel('employed_at'),
> __.as('c').hasLabel('Company'),
> )
>
> Thoughts?
>
> Dave
>