As I continue to tinker with match() I'm finding that in actual usage, I
want it to behave like the original match(). Basically, with the current
match() proposal we forced use of select() to follow match() as a standi-n
for RETURN (if i read the original posts right). If we don't have
match().select() then match() returns Optional.empty. I'm not sure that's
necessary and it actually creates a complication I'd called out with
serialization support for that and for language variants. This all seems
easily resolved by just making the new match work like the old one and have
it produce all the bindings as a Map if select() isn't present. So instead
of:

gremlin> g.match("MATCH (a:person)-[:knows]->(b:person)").limit(1)
==>Optional.empty
gremlin> g.match("MATCH (a:person)-[:knows]->(b:person)")
match() cannot be a terminal step — use select() to access bound variables
Type ':help' or ':h' for help.
Display stack trace? [yN]n
gremlin> g.match("MATCH (a:person)-[:knows]->(b:person)").limit(10)
==>Optional.empty
==>Optional.empty

we'd instead get:

gremlin> g.match("MATCH (a:person)-[:knows]->(b:person)")
==>[a:v[1],b:v[2]]
==>[a:v[1],b:v[4]]

which is essentially, all the bindings and equivalent to the old way:

gremlin> g.V().
......1>
match(__.as("a").hasLabel("person").out("knows").hasLabel("person").as("b"))
==>[a:v[1],b:v[2]]
==>[a:v[1],b:v[4]]

As when select() was forced, i don't think this precludes the use of
select() here. It in fact seems to fit quite well as it did before. I also
don't think it interferes with potential support of RETURN which would just
change which bindings are ultimately populated to the Map. We should also
get the original match().where() syntax immediately as a result of this
shift.


On Tue, Apr 14, 2026 at 7:45 AM Stephen Mallette <[email protected]>
wrote:

> Over the weekend, I experimented a bit with this proposal from Andrii,
> that was of positive discussion on this list a few months back, that helped
> bring some formality to the idea of making match() step take any
> declarative query language (like GQL) such that its results would be
> returned into a Gremlin traversal stream :
>
>
> https://github.com/apache/tinkerpop/blob/master/docs/src/dev/future/proposal-declarative-match-step-9.asciidoc
>
> I have the basics of it working:
>
> gremlin> g.match("MATCH (a:person)-[:knows]->(b:person)").select("a","b")
> ==>[a:v[1],b:v[2]]
> ==>[a:v[1],b:v[4]]
> gremlin> g.match("MATCH
> (a:person)-[:knows]->(b:person)").select("a","b").by('name')
> ==>[a:marko,b:vadas]
> ==>[a:marko,b:josh]
> gremlin> g.match("MATCH (a:person)-[:knows]->(b:person),
> (b)-[:created]->(s:software)").
> ......1>   select("a","b","s").by("name").by("name").by("name")
> ==>[a:marko,b:josh,s:lop]
> ==>[a:marko,b:josh,s:ripple]
>
> initially, I think this feature will come with the added restriction that
> match() is a provider implemented step for 4.0. In other words, there won't
> be generic support provided by the TinkerPop query processing engine. At
> least, that would not be the initial main goal. It could however be
> reserved for a future goal that arrives for 4.1 or some other later
> version. For 4.0, the focus would be a basic implementation for TinkerGraph
> only with a simple "TinkerGQL" grammar (i.e. a subset supported by
> TinkerGraph that focuses on pattern matching and basic filtering).
>
> I think that with these sorts of restrictions, this feature can
> comfortably land for 4.0 among the myriad of other things 4.0 will contain.
> It will allow both provider and user feedback on the feature in general and
> help set the stage for future work in this area. It will take a few days
> yet to get this to a PR stage - in the meantime please let me know if you
> have any thoughts on this.
>
>
>

Reply via email to