kenhuuu commented on code in PR #3437: URL: https://github.com/apache/tinkerpop/pull/3437#discussion_r3359459715
########## docs/src/reference/the-traversal.asciidoc: ########## @@ -2660,228 +2660,349 @@ link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gre [[match-step]] === Match Step -The `match()`-step (*map*) provides a more link:http://en.wikipedia.org/wiki/Declarative_programming[declarative] -form of graph querying based on the notion of link:http://en.wikipedia.org/wiki/Pattern_matching[pattern matching]. -With `match()`, the user provides a collection of "traversal fragments," called patterns, that have variables defined -that must hold true throughout the duration of the `match()`. When a traverser is in `match()`, a registered -`MatchAlgorithm` analyzes the current state of the traverser (i.e. its history based on its -<<path-data-structure,path data>>), the runtime statistics of the traversal patterns, and returns a traversal-pattern -that the traverser should try next. The default `MatchAlgorithm` provided is called `CountMatchAlgorithm` and it -dynamically revises the pattern execution plan by sorting the patterns according to their filtering capabilities -(i.e. largest set reduction patterns execute first). For very large graphs, where the developer is uncertain of the -statistics of the graph (e.g. how many `knows`-edges vs. `worksFor`-edges exist in the graph), it is advantageous to -use `match()`, as an optimal plan will be determined automatically. Furthermore, some queries are much easier to -express via `match()` than with single-path traversals. +Gremlin is a mostly imperative-style query language, but it also supports a means for defining a query declaratively, +where users get a high degree of flexibility in deciding what parts of their query might be better written in one +fashion or the other. Having this choice helps promote better query readability and query ergonomics and offers graph +databases an opportunity to expose multi-language features and optimizations. This feature is provided by way of the +`match()`-step. - "Who created a project named 'lop' that was also created by someone who is 29 years old? Return the two creators." +The `match()`-step (*map*) accepts a declarative query string, like link:https://www.iso.org/standard/76120.html[GQL], +and executes it against the graph. TinkerPop ships an optional module, `gql-gremlin`, that provides the +<<tinkergql,TinkerGQL>> dialect — a deliberate subset of ISO GQL `MATCH` syntax — which any graph system provider +may adopt. Providers may also implement their own declarative query engine with a completely different language. +*Whether `match()` is supported at all depends on the graph system being used.* Consult the documentation for your +graph system to determine what query languages and syntax are accepted. -image::match-step.png[width=500] +Since `match()` is a provider-specific feature, a traversal that uses `match()` against a graph system that has not +implemented support for it will throw an exception when the step is reached. The examples below are executed against +TinkerGraph, which ships TinkerGQL support out of the box (see <<tinkergraph-gql>>), demonstrating how the step +works in practice. What your graph system accepts may be entirely different. + +The step can be used in two ways. As a spawn step directly on a `GraphTraversalSource`, the pattern query is +evaluated once and each result becomes a traverser: [gremlin-groovy,modern] ---- -g.V().match( - __.as('a').out('created').as('b'), - __.as('b').has('name', 'lop'), - __.as('b').in('created').as('c'), - __.as('c').has('age', 29)). - select('a','c').by('name') +g.match("MATCH (a:person)-[:knows]->(b:person)") ---- -Note that the above can also be more concisely written as below which demonstrates that standard inner-traversals can -be arbitrarily defined. +As a mid-traversal step, the pattern is applied independently for each incoming traverser — +the full graph is scanned against the pattern for every traverser rather than using the traverser's +current element as a seed. Each result row is emitted as a separate output traverser: [gremlin-groovy,modern] ---- -g.V().match( - __.as('a').out('created').has('name', 'lop').as('b'), - __.as('b').in('created').has('age', 29).as('c')). - select('a','c').by('name') +g.V().hasLabel("software"). + match("MATCH (a:person)-[:knows]->(b:person)") ---- -In order to improve readability, `as()`-steps can be given meaningful labels which better reflect your domain. The -previous query can thus be written in a more expressive way as shown below. +Each result row is emitted as a `Map<String, Object>` whose keys are the named variable names from the pattern and +whose values are the bound graph elements. + +A common pattern is to follow `match()` with a `select()` to extract and then transform specific variables by name. +Anonymous pattern elements (those without a variable name) are not exposed and cannot be selected. [gremlin-groovy,modern] ---- -g.V().match( - __.as('creators').out('created').has('name', 'lop').as('projects'), <1> - __.as('projects').in('created').has('age', 29).as('cocreators')). <2> - select('creators','cocreators').by('name') <3> +g.match("MATCH (a:person)-[:knows]->(b:person)") Review Comment: ```suggestion g.match("MATCH (a:person)-[:knows]->(b:person)"). ``` -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
