Good day.

I propose new semantics for the match step in Gremlin, which we discussed
briefly in the Discord chat. The current ideas listed partially summarize
ideas suggested by several discussion participants.

The current semantics of the match step are complex to optimize, so users
do not use this step in practice, and DB vendors do not recommend using
match step in queries.

Instead, what is proposed is to provide a new match step based on
declarative semantics.

Signature of this step is quite simple: Travervsal<S, E> match(String
matchQuery).

Where matchQuery is a match statement written in declarative query language
supported by the provider, I will use GQL as an example below.

This step will require the language as a configuration parameter provided
using with the step.

So the simplest query will look like:

g.match(“MATCH (person:Person)-[:knows]->(friend:Person)”).with(“language”,
“GQL”)

match step can accept query parameters, so if we provide a query like
g.match(“MATCH
(p:Person WHERE p.name = $personName)RETURN p.email”).with(“language”,
“GQL”)

we may use parameter bindings, but it will work only for interaction with
Gremlin Server, so instead, I propose an additional modulator step:
withParameter(String
name, Object value)

In such case final version will look like: g.match(“MATCH (p:Person WHERE
p.name = $personName) RETURN p.email”).with(“language”,
“GQL”).withParameter(“personName”, “Stephen”)

Alongside the version of withParameter step that provides the name of the
query parameter, a version with the following signature should also be
provided: withParameter(int index, Object value) for query languages that
support indexed parameters with/instead of named parameters.

Because we already introduced one modulator step, it is reasonable to
consider replacing it with step by more specific withQueryLanguage()
modulator step that will allow us to add more expressiveness to the
resulting queries.

In such case final version will look like:  g.match(“MATCH (p:Person WHERE
p.name = $personName) RETURN
p.email”).withQueryLanguage(“GQL”).withParameter(“personName”, “Stephen”)

As for the scope of application of this step, I recommend making it behave
exactly as it is implemented for the V() and E() steps. It could be added
in the middle of GraphTraversal, but the execution result will be the same
pattern matching execution applied to the whole graph stored in the
database (not to the item filtered/transformed by the previous steps).

It also means that match step will be added to the GraphTraversalSource.

As for the format of the output of the match step, I would recommend the
following:

1.  If the match statement returns an Element instance, it is returned as
is.

2.  Otherwise, it should return any value that is allowed to be a property
value in Element.

3. I would add an optional recommendation to return either Element or
Map<String,
?>  where the key of the map is the result a projection of the query result
which in case of query  g.match(“MATCH (p:Person WHERE p.name =
$personName) RETURN
p.email”).withQueryLanguage(“GQL”).withParameter(“personName”, “Stephen”)

will look like {“p.email”: “s...@gmail.com”}. Following this optional
recommendation will, IMHO, improve user experience.

This step should be restricted to executing only idempotent queries.

I would also recommend adding versions of withParameter() that accept
Traversal as a value of the parameters, namely:
1.  withParameter(String name, TraversalSource value)

2.  withParameter(int index, TraversalSource value)



The current version of the match step should be deprecated and then removed.

I want to thank Stephen Mallette, whose initial idea closely aligned with
ours and who actively contributed to our discussions.

I'm looking forward to your thoughts, observations, and any other feedback
you may have.

Best Regards,
YouTrackDB development lead
Andrii Lomakin

Reply via email to