| //// |
| Licensed to the Apache Software Foundation (ASF) under one or more |
| contributor license agreements. See the NOTICE file distributed with |
| this work for additional information regarding copyright ownership. |
| The ASF licenses this file to You under the Apache License, Version 2.0 |
| (the "License"); you may not use this file except in compliance with |
| the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| //// |
| [[gremlin-semantics]] |
| = Gremlin Semantics |
| |
| image:tinkerpop-meeting-room.png[] |
| |
| This section provides details on Gremlin language operational semantics. Describing these semantics and reinforcing |
| them with tests in the Gremlin test suite makes it easier for providers to implement the language and for the |
| TinkerPop Community to have better consistency in their user experiences. While the general Gremlin test suite offers |
| an integrated approach to testing Gremlin queries, the `@StepClassSemantics` oriented tests found |
| link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features[here] are especially focused to the |
| definitions found in this section. References to the location of specific tests can be found throughout the |
| sub-sections below. |
| |
| == Types |
| |
| The TinkerPop query execution runtime is aligned with Java primitives and handles the following primitive types: |
| |
| * Boolean |
| * Integer |
| ** Byte (int8) |
| ** Short (int16) |
| ** Integer (int32) |
| ** Long (int64) |
| ** BigInteger |
| * Decimal |
| ** Float (32-bit) (including +/-Infinity and NaN) |
| ** Double (64-bit) (including +/-Infinity and NaN) |
| ** BigDecimal |
| * String |
| * UUID |
| * Date |
| * `nulltype` |
| ** Has only one value in its type space - the "undefined" value `null` |
| |
| NOTE: TinkerPop has a bit of a JVM-centric view of types as it was developed within that ecosystem. |
| |
| Graph providers may not support all of these types depending on the architecture and implementation. Therefore |
| TinkerPop must provide a way for Graph providers to override the behavior while it has its own default behavior. Also |
| when some types are not supported Graph providers needs to map unsupported types into supported types internally. This |
| mapping can be done in either information-preserving manner or non-preserving manner. Graph providers must tell which |
| mapping they support through `Graph.Features` as well as which types they support. |
| |
| * Which primitive types are supported |
| ** Boolean, Integer, Float, String, UUID and Date |
| ** TinkerPop by default supports all of them |
| * Which integer types are supported |
| ** TinkerPop by default supports int8 (Byte), int16 (Short), int32 (Integer), int64 (Long) and BigInteger in Java |
| * Which float types are supported |
| ** TinkerPop by default supports all as float, double, and BigDecimal in Java |
| |
| In addition to these, there are composite types as follows: |
| |
| * Graph Element |
| ** Vertex |
| ** Edge |
| ** VertexProperty |
| * Property (edge properties and meta properties) |
| ** (Key, Value) pair |
| ** Key is String, Value is any of the primitive types defined above |
| * Path |
| * List |
| * Map |
| * Map.Entry |
| * Set |
| |
| === Numeric Type Promotion |
| |
| TinkerPop performs type promotion a.k.a type casting for Numbers. Numbers are Byte, Short, Integer, Long, Float, |
| Double, BigInteger, and BigDecimal. In general, numbers are compared using semantic equivalence, without regard for |
| their specific type, e.g. `1 == 1.0`. |
| |
| For comparisons numeric types are promoted as follows: |
| |
| * First determine whether to use floating point or not. If any numbers in the comparison are floating point then we |
| convert all of them to floating point. |
| * Next determine the maximum bit size of the numerics being compared. |
| * If any floating point are present: |
| ** If the maximum bit size is 32 (up to Integer/Float), we compare as Float |
| ** If the maximum bit size is 64 (up to Long/Double), we compare as Double |
| ** Otherwise we compare as BigDecimal |
| * If no floating point are present: |
| ** If the maximum bit size is 8 we compare as Byte |
| ** If the maximum bit size is 16 we compare as Short |
| ** If the maximum bit size is 32 we compare as Integer |
| ** If the maximum bit size is 64 we compare as Long |
| ** Otherwise we compare as BigInteger |
| |
| BigDecimal and BigInteger may not be supported depending on the language and Storage, therefore the behavior of type |
| casting for these two types can vary depending on a Graph provider. |
| |
| For numeric type mathematical operations (div/mul/add/sub), types are promoted as follows: |
| |
| On math operations (when used in steps such as sum/sack) the highest common number class between |
| the two inputs is used. Any number being floating point forces a floating point result. |
| If an overflow occurs (either integer or floating-point), the method promotes the precision |
| by increasing the bit width, until a suitable type is found. If no suitable type exists |
| (e.g., for very large integers beyond 64-bit), an Arithmetic Exception is thrown. |
| For floating-point numbers, if double overflows, the result is Double.POSITIVE_INFINITY |
| or Double.NEGATIVE_INFINITY instead of an exception. |
| |
| [[gremlin-semantics-concepts]] |
| == Comparability, Equality, Orderability, and Equivalence |
| |
| This section of the document attempts to more clearly define the semantics for different types of value comparison |
| within the Gremlin language and reference implementation. There are four concepts related to value comparison: |
| |
| **Equality** |
| |
| Equality semantics is used by the equality operators (`P.eq/neq`) and contains operators derived from them |
| (`P.within/without`). It is also used for implicit `P.eq` comparisons, for example `g.V().has("age", 25)` - equality |
| semantics are used to look up vertices by `age` when considering the value. |
| |
| **Comparability** |
| |
| Comparability semantics is used by the compare operators (`P.lt/lte/gt/gte`) and operators derived from them |
| (`P.inside/outside/between`) and defines the semantics of how to compare two values. |
| |
| **Orderability** |
| |
| Orderability semantics defines how two values are compared in the context of an `order()` operation. These semantics |
| have important differences from Comparability. |
| |
| **Equivalence** |
| |
| Equivalence semantics are slightly different from Equality and are used for operations such as `dedup()` and `group()`. |
| Key differences include handling of numeric types and NaN. |
| |
| Both Equality and Equivalence can be understood as complete, i.e. the result of equality and equivalence checks is |
| always either `TRUE` or `FALSE` (in particular, it never returns `nulltype` or throws an exception). Similarly, |
| Orderability can be also understood as complete - any two values can be compared without error for ordering purposes. |
| Comparability semantics are not complete with respect to traditional binary boolean semantics, as certain comparisons |
| cannot be proved as either `TRUE` or `FALSE`. Common examples of such cases are Comparability against `NaN`, cross-type |
| Comparability (e.g. `String` vs `Numeric`). For the purposes of Comparability within Gremlin, any such incomputable |
| comparison is defined to be `FALSE`, and traditional binary boolean semantics apply thereafter. |
| |
| [[gremlin-semantics-equality-comparability]] |
| === Equality and Comparability |
| |
| <<Equality,Equality>> and <<Comparability,Comparability>> can be understood to be semantically aligned with one another. |
| As mentioned above, <<Equality,Equality>> is used for `P.eq/neq` (and derived predicates) and |
| <<Comparability,Comparability>> is used for `P.lt/lte/gt/gte` (and derived predicates). |
| If we define Comparability using a `compare()` function over `A` and `B` as follows: |
| |
| [source,text] |
| ---- |
| If (A, B) are Comparable per Gremlin semantics, then: |
| For A < B, Comparability.compare(A, B) < 0 |
| For A > B, Comparability.compare(A, B) > 0 |
| For A == B, Comparability.compare(A, B) == 0 |
| If (A, B) not Comparable, then: |
| Comparability.compare(A, B) => ERROR |
| ---- |
| |
| Then we can define Equality using an `equals()` function over `A` and `B` that acts as a strict binary |
| reduction of `Comparability.compare(A, B) == 0`: |
| |
| [source,text] |
| ---- |
| For any (A, B): |
| Comparability.compare(A, B) == 0 implies Equality.equals(A, B) == TRUE |
| Comparability.compare(A, B) <> 0 implies Equality.equals(A, B) == FALSE |
| Comparability.compare(A, B) => ERROR implies Equality.equals(A, B) == FALSE |
| ---- |
| |
| The following table illustrates how <<Equality,Equality>> and <<Comparability,Comparability>> operate under various |
| classes of comparison: |
| |
| |=== |
| |Class|Arguments|<<Comparability,Comparability>>|<<Equality,Equality>> |
| |
| |Comparisons Involving `NaN`|`(NaN,X)` + |
| |
| where `X` = any value, including `NaN`|`FALSE` + |
| |
| Comparing `NaN` to anything (including itself) cannot be evaluated.|`FALSE` |
| |
| |Comparisons Involving `null`|`(null,null)`|`compare() == 0`|`TRUE` |
| ||`(null, X)`|`FALSE` + |
| |
| Since `nulltype` is its own type, this falls under the umbrella of cross-type comparisons. |`FALSE` |
| |Comparisons within the same type family (i.e. String vs. String, Number vs. Number, etc.)|`(X, Y)` + |
| |
| where `X` and `Y` of same type|Result of `compare()` depends on type semantics, defined below.|`TRUE` iff `compare() == 0` |
| |Comparisons across types (i.e. String vs. Number)|`(X, Y)` + |
| |
| where `X` and `Y` of different type|`FALSE`|`FALSE` |
| |
| |=== |
| |
| ==== Equality and Comparability Semantics by Type |
| |
| For <<Equality,Equality>> and <<Comparability,Comparability>> evaluation of values within the same type family, we |
| define the semantics per type family as follows. |
| |
| ===== Number |
| |
| Numbers are compared using type promotion, described above. As such, `1 == 1.0`. |
| |
| Edge cases: |
| |
| * `-0.0 == 0.0 == +0.0` |
| * `+INF == +INF`, `-INF == -INF`, `-INF != +INF` |
| ** `Float.±Infinity` and `Double.±Infinity` adhere to the same type promotion rules. |
| * As described above `NaN` is not <<Equality,Equal>> and not <<Comparability,Comparable>> to any Number (including itself). |
| |
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/semantics/Equality.feature[Equality Tests - Scenarios prefixed with "Primitives_Number_"] |
| |
| ===== nulltype |
| |
| As described in the table above, `null == null`, but is not <<Equality,Equal>> and not <<Comparability,Comparable>> to |
| any non-`null` value. |
| |
| ===== Boolean |
| |
| For Booleans, `TRUE == TRUE`, `FALSE == FALSE`, `TRUE != FALSE`, and `FALSE < TRUE`. |
| |
| ===== String |
| |
| We assume the common lexicographical order over unicode strings. `A` and `B` are compared lexicographically, and |
| `A == B` if `A` and `B` are lexicographically equal. |
| |
| ===== UUID |
| |
| UUID is evaluated based on its String representation. However, `UUID("b46d37e9-755c-477e-9ab6-44aabea51d50")` and the |
| String `"b46d37e9-755c-477e-9ab6-44aabea51d50"` are not <<Equality,Equal>> and not <<Comparability,Comparable>>. |
| |
| ===== Date |
| |
| Dates are evaluated based on the numerical comparison of Unix Epoch time. |
| |
| ===== Graph Element (Vertex / Edge / VertexProperty) |
| |
| If they are the same type of Element, these are compared by the value of their `T.id` according to the semantics for |
| the particular primitive type used for ids (implementation-specific). Elements of different types are |
| not <<Equality,Equal>> and not <<Comparability,Comparable>>. |
| |
| ===== Property |
| |
| Properties are compared first by key (String semantics), then by value, according to the semantics for the particular |
| primitive type of the value. Properties with values in different type families are |
| not <<Equality,Equal>> and not <<Comparability,Comparable>>. |
| |
| ===== List |
| |
| Lists are compared pairwise, element-by-element, in their natural list order. For each element, if the pairs are |
| <<Equality and Comparability,Equal>>, we simply move on to the next element pair until we encounter a pair which is not |
| comparable, or whose `Comparability.compare()` value is non-zero, and we return that value. Lists can be evaluated |
| for <<Equality and Comparability,Equality and Comparability>> even if they contain multiple types of elements, so long |
| as their elements are pairwise comparable per <<Equality and Comparability,Equality/Comparability>> semantics. During |
| this element by element comparison, if iteration `A` exhausts its elements before iteration `B` then `A < B`, and |
| vice-versa. |
| |
| Empty lists are equal to other empty lists and less than non-empty lists. |
| |
| |=== |
| |`A`|`B`|`compare(A,B)`|`P`|Reason |
| |
| |`[]`|`[]`|`0`|`P.eq`|empty lists are equal |
| |`[]`|`[1]`|`-1`|`P.lt`|empty < non-empty |
| |`[1]`|`[]`|`1`|`P.gt`|non-empty > empty |
| |`[1,2,3]`|`[1,2,3]`|`0`|`P.eq`|pairwise equal |
| |`[1,2,3]`|`[1,2,4]`|`-1`|`P.lt`|pairwise equal until last element: `3 < 4` |
| |`[1,2,3]`|`[1,2,3,4]`|`-1`|`P.lt`|`A` exhausts first |
| |`[1,2,3,4]`|`[1,2,3]`|`1`|`P.gt`|`B` exhausts first |
| |`[1,2]`|`[1.0,2.0]`|`0`|`P.eq`|type promotion |
| |`[1,"a"]`|`[1,"b"]`|`-1`|`P.lt`|pairwise <<Comparability,Comparable>> and `"a" < "b"` |
| |`[1]`|`["a"]`|`ERROR`|`P.neq`|cross-type comparison |
| |=== |
| |
| ===== Path |
| |
| <<Equality and Comparability,Equality and Comparability>> semantics for `Paths` are similar to those for `Lists`, described above (though |
| `Paths` and `Lists` are still of different types and thus not <<Equality,Equal>> and not <<Comparability,Comparable>>). |
| |
| ===== Set |
| |
| `Sets` are compared pairwise, element-by-element, in the same way as `Lists`, but they are compared in sorted order |
| using <<Orderability,Orderability>> semantics to sort (described further below). We use <<Orderability,Orderability>> |
| semantics for ordering so that `Sets` containing multiple element types can be properly sorted before being compared. |
| |
| For example: |
| |
| |=== |
| |`A`|`B`|`compare(A,B)`|`P`|Reason |
| |
| |`{1, 2}`|`{2, 1}`|`0`|`P.eq`|sort before compare |
| |`{1, "foo"}`|`{"foo", 1}`|`0`|`P.eq`|we use <<Orderability,Orderability>> semantics to sort across types |
| |=== |
| |
| Sets do introduce a bit of semantic stickiness, in that on the one hand they do respect type promotion semantics for |
| Equality and Comparability: |
| |
| [source,text] |
| ---- |
| {1, 2} == {1.0, 2.0} |
| ---- |
| |
| But on the other hand they also allow two elements that would be equal (and thus duplicates) according to type |
| promotion: |
| |
| [source,text] |
| ---- |
| {1, 1.0, 2} is a valid set and != {1, 2} |
| ---- |
| |
| We allow some "wiggle-room" in the implementation for providers to decide how to handle this logical inconsistency. The |
| reference implementation allows for semantically equivalent numerics to appear in a set (e.g `{1, 1.0}`), while at the |
| same time evaluating the same semantically equivalent numerics as equal during pairwise comparison across sets (e.g. |
| `{1,2} == {1.0,2.0}`). |
| |
| ===== Map |
| |
| 'Map' semantics can be thought of as similar to `Set` semantics for the entry set the comprises the `Map`. So again, |
| we compare pairwise, entry-by-entry, in the same way as `Lists`, and again, we first sort the entries using |
| <<Orderability,Orderability>> semantics. Map entries are compared first by key, then by value using the |
| <<Equality and Comparability Semantics by Type,Equality and Comparability>> semantics that apply to the specific type |
| of key and value. |
| |
| Maps semantics have the same logical inconsistency as set semantics, because of type promotion. Again, we leave room |
| for providers to decide how to handle this in their implementation. The reference implementation allows for semantically |
| equivalent keys to appear in a map (e.g. `1` and `1.0` can both be keys in the same map), but when comparing maps we |
| treat pairwise entries with semantically equivalent keys as the same. |
| |
| ==== Comparability of Types |
| |
| The `P.typeOf()` predicate enables type-based filtering in TinkerPop using inheritance-aware comparison, where a value |
| matches if it is the specified type or any of its subtypes. |
| |
| ===== GType Enums |
| |
| Based on the support type space, we have defined a `GType` enum, which contains a set of enumerations that is used for |
| type casting (`asNumber()`) and comparison (`P.typeOf()`) operations. |
| |
| * **Numeric types**: `INT`, `LONG`, `DOUBLE`, `FLOAT`, `BYTE`, `SHORT`, `BIGDECIMAL`, `BIGINT` |
| * **General types**: `STRING`, `BOOLEAN`, `CHAR`, `UUID`, `BINARY` |
| * **Collection types**: `LIST`, `SET`, `MAP` |
| * **Graph types**: `VERTEX`, `EDGE`, `PROPERTY`, `VPROPERTY`, `PATH`, `TREE`, `GRAPH` |
| * **Temporal types**: `DATETIME`, `DURATION` |
| * **Special types**: `NULL`, `NUMBER` (supertype for all numeric types) |
| |
| ===== GlobalTypeCache |
| |
| Providers can register custom types outside the TinkerPop type space using the `GlobalTypeCache`, making them available |
| for `P.typeOf(String)` filtering. Unregistered string inputs will throw an `IllegalArgumentException`. |
| |
| The `registerDataType()` method registers the class's simple name by default, or accepts a custom string name. Providers |
| should use PascalCase following Java conventions and prefix type names to avoid conflicts |
| (e.g., `ProviderPrefix:SimpleTypeName`). |
| |
| Do note that the type cache only enables type recognition for filtering. Custom types still require separate |
| serialization support - clients without custom serializers cannot deserialize these types. |
| |
| [[gremlin-semantics-orderability]] |
| === Orderability |
| |
| <<Equality and Comparability,Equality and Comparability>> were described in depth in the sections above, and their |
| semantics map to the `P` predicates. <<Comparability,Comparability>> in particular is limited to |
| comparison of values within the same type family. Comparability is complete within a given type (except for `NaN`, |
| which results in `FALSE` for any comparison), but returns `FALSE` for comparisons across types (e.g., an integer cannot |
| be compared to a string). |
| |
| Orderability semantics are very similar to Comparability for the most part, except that Orderability will never result |
| in `ERROR` for comparison of any two values - even if two values are incomparable according to Comparability semantics |
| we will still be able to determine their respective order. This allows for a total order across all Gremlin values. In |
| the reference implementation, any step using `Order.asc` or `Order.desc` (e.g. OrderGlobalStep, OrderLocalStep) will |
| follow these semantics. |
| |
| To achieve this globally complete order, we need to address any cases in Comparability which are incomputable, we must |
| define a global order across type families, and we must provide semantics for ordering "unknown" |
| values (for cases of in-process JVM implementations, like the TinkerGraph). |
| |
| We define the type space, and the global order across the type space as follows: |
| |
| [source,text] |
| ---- |
| 1. nulltype |
| 2. Boolean |
| 3. Number |
| 4. Date |
| 5. String |
| 6. Vertex |
| 7. Edge |
| 8. VertexProperty |
| 9. Property |
| 10. Path |
| 11. Set |
| 12. List |
| 13. Map |
| 14. Unknown |
| ---- |
| |
| Values in different type spaces will be ordered according to their priority (e.g. all Numbers < all Strings). |
| |
| Within a given type space, Orderability determines if two values are ordered at the same position or one value is |
| positioned before or after the another. When the position is identical, which value comes first (in other words, |
| whether it should perform stable sort) depends on graph providers' implementation. |
| |
| To allow for this total ordering, we must also address the cases in <<Equality and Comparability,Comparability>> where |
| the comparison is incomputable: |
| |
| |=== |
| |Incomputable Scenario|Comparability|Orderability |
| |
| |Comparison against `NaN`|`NaN` not comparable to anything, including itself.|`NaN` appears after `+Infinity` in the numeric type space. |
| |Comparison across types|Cannot compare values of different types. This includes the `nulltype`.|Subject to a total |
| type ordering where every value of type A appears before or after every value of Type B per the priorty list above. |
| |=== |
| |
| ==== Key differences from Comparability |
| |
| One key difference to note is that we use Orderability semantics to compare values within containers (`List`, `Set`, |
| `Path`, `Map`, `Property`) rather than using Comparability semantics (i.e. Orderability all the way down). |
| |
| ===== Numeric Ordering |
| |
| Same as Comparability, except `NaN` is equivalent to `NaN` and is greater than all other Numbers, including `+Infinity`. |
| Additionally, because of type promotion (`1` == `1.0`), numbers of the same value but of different numeric types will |
| not have a stable sort order (`1` can appear either before or after `1.0`). |
| |
| ===== Property |
| |
| Same as Comparability, except Orderability semantics are used for the property value. |
| |
| ===== Iterables (Path, List, Set, Map) |
| |
| Same as Comparability, except Orderability semantics apply for the pairwise element-by-element comparisons. |
| |
| ===== Unknown Types |
| |
| For Orderability semantics, we allow for the possibility of "unknown" types. If the "unknown" arguments are of the same |
| type, we use `java.lang.Object#equals()` and `java.lang.Comparable` (if implemented) to determine their natural order. |
| If the unknown arguments are of different types or do not define a natural order, we order first by Class, |
| then by `Object.toString()`. |
| |
| [[gremlin-semantics-equivalence]] |
| === Equivalence |
| |
| Equivalence defines how TinkerPop deals with two values to be grouped or de-duplicated. Specifically it is necessary |
| for the `dedup()` and `group()` steps in Gremlin. |
| |
| For example: |
| |
| [source,text] |
| ---- |
| // deduplication needs equivalence over two property values |
| gremlin> g.V().dedup().by("name") |
| // grouping by equivalence over two property values |
| gremlin> g.V().group().by("age") |
| ---- |
| |
| Like Equality, Equivalence checks always return `true` or `false`, never `nulltype` or `error`, nor do they produce |
| exceptions. For the most part Equivalence and Equality are the same, with the following key differences: |
| |
| * Equivalence ignores type promotion semantics, i.e. two values of different types (e.g. 2^^int vs. 2.0^^float) are |
| always considered to be non-equivalent. |
| * `NaN` Equivalence is the reverse of Equality: `NaN` is equivalent to `NaN` and not |
| Equivalent to any other Number. |
| |
| === Further Reference |
| |
| ==== Mapping for P |
| |
| The following table maps the notions proposed above to the various `P` operators: |
| |
| [%header] |
| |================ |
| |Predicate|Concept |
| |P.eq |Equality |
| |P.neq |Equality |
| |P.within |Equality |
| |P.without|Equality |
| |P.lt |Comparability |
| |P.gt |Comparability |
| |P.lte |Equality, Comparability |
| |P.gte |Equality, Comparability |
| |P.inside |Comparability |
| |P.outside|Comparability |
| |P.between|Equality, Comparability |
| |================ |
| |
| ==== See Also |
| |
| link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/semantics/Equality.feature[Equality Tests], |
| link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/semantics/Comparability.feature[Comparability Tests] |
| |
| == Steps |
| |
| While TinkerPop has a full test suite for validating functionality of Gremlin, tests alone aren't always exhaustive or |
| fully demonstrative of Gremlin step semantics. It is also hard to simply read the tests to understand exactly how a |
| step is meant to behave. This section discusses the semantics for individual steps to help users and providers |
| understand implementation expectations. |
| |
| [[adde-step]] |
| === addE() |
| |
| *Description:* Adds an edge to the graph. |
| |
| *Syntax:* `addE(String edgeLabel)` | `addE(Traversal<?, String> edgeLabelTraversal)` |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Start Step |Mid Step |Modulated |Domain |Range |
| |Y |Y |`from()`/`to()` |`any` |`Edge` |
| |========================================================= |
| |
| *Arguments:* |
| |
| * `edgeLabel` - The label of the edge to add. |
| * `edgeLabelTraversal` - A traversal that produces the label of the edge to add. |
| |
| *Modulation:* |
| |
| * `from()` - Specifies the source vertex for the edge. |
| * `to()` - Specifies the target vertex for the edge. |
| |
| *Considerations:* |
| |
| The `addE()` step can be used as both a start step and a mid-traversal step. When used as a start step, both `from()` |
| and `to()` must be specified. When used as a mid-traversal step, the current traverser becomes the source vertex and |
| only `to()` needs to be specified. |
| |
| The gremlin-lang grammar only permits `Traversal` and `String` (alias for `__.select(String)`) arguments in `from()` and |
| `to()`. The `Traversal` must either produce a `Vertex` which is attachable to the graph, or it must produce the id of an |
| existing `Vertex` in the graph. `GraphTraversal` implementations in GLVs may optionally support `from(Vertex)` and |
| `to(Vertex)` as syntactic sugar. If translating to gremlin-lang scripts, these sugared modulators must be converted to |
| `from(__.V(vertex.id()))` or `from(__.constant(vertex.id()))` (and equivalents for `to()`). |
| |
| *Exceptions* |
| |
| * If the edge label is null, an `IllegalArgumentException` will be thrown. |
| |
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddEdgeStep.java[source], |
| link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddEdgeStartStep.java[source (start)], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#addedge-step[reference] |
| |
| [[addv-step]] |
| === addV() |
| |
| *Description:* Adds a vertex to the graph. |
| |
| *Syntax:* `addV()` | `addV(String vertexLabel)` | `addV(Traversal<?, String> vertexLabelTraversal)` |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Start Step |Mid Step |Modulated |Domain |Range |
| |Y |Y |N |`any` |`Vertex` |
| |========================================================= |
| |
| *Arguments:* |
| |
| * `vertexLabel` - The label of the vertex to add. |
| * `vertexLabelTraversal` - A traversal that produces the label of the vertex to add. |
| |
| *Modulation:* |
| |
| None |
| |
| *Considerations:* |
| |
| The `addV()` step can be used as both a start step and a mid-traversal step. If no label is provided, the default |
| vertex label for the graph will be used. |
| |
| *Exceptions* |
| |
| * If the vertex label is null, an `IllegalArgumentException` will be thrown. |
| |
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddVertexStep.java[source], |
| link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddVertexStartStep.java[source (start)], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#addvertex-step[reference] |
| |
| [[all-step]] |
| === all() |
| |
| *Description:* Filters array data from the traversal stream if all of the array's items match the supplied predicate. |
| |
| *Syntax:* `all(P predicate)` |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Start Step |Mid Step |Modulated |Domain |Range |
| |N |Y |N |`List`/`array`/`Iterable`/`Iterator` |`List`/`array`/`Iterable`/`Iterator` |
| |========================================================= |
| |
| *Arguments:* |
| |
| * `predicate` - The predicate to use to test each value in the array data. |
| |
| *Modulation:* |
| |
| None |
| |
| *Considerations:* |
| |
| Each value will be tested using the supplied predicate. Empty lists always pass through and null/non-list traversers |
| will be filtered out of the Traversal Stream. |
| |
| *Exceptions* |
| |
| * A GremlinTypeErrorException will be thrown if one occurs and no other value evaluates to false. |
| |
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/AllStep.java[source], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#all-step[reference] |
| |
| [[aggregate-step]] |
| === aggregate() |
| |
| *Description:* Collects all objects in the traversal into a collection. |
| |
| *Syntax:* `aggregate(String sideEffectKey)` |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Start Step |Mid Step |Modulated |Domain |Range |
| |N |Y |`by()` |`any` |`any` |
| |========================================================= |
| |
| *Arguments:* |
| |
| * `sideEffectKey` - The name of the side-effect key that will hold the aggregated objects. |
| |
| *Modulation:* |
| |
| * `by()` - Determines how to transform the object before aggregating. If not specified, the object itself is used. |
| |
| *Considerations:* |
| |
| The `aggregate()` step is a side-effect step that collects objects but passes the traverser to the next step unchanged. |
| The aggregated objects can be accessed later using the `cap()` step. |
| |
| *Exceptions* |
| |
| None |
| |
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/AggregateStep.java[source], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#aggregate-step[reference] |
| |
| [[and-step]] |
| === and() |
| |
| *Description:* Ensures that all provided traversals yield a result. |
| |
| *Syntax:* `and(Traversal<?, ?>... andTraversals)` |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Start Step |Mid Step |Modulated |Domain |Range |
| |N |Y |N |`any` |`any` |
| |========================================================= |
| |
| *Arguments:* |
| |
| * `andTraversals` - One or more traversals that will be executed against the current object. |
| |
| *Modulation:* |
| |
| None |
| |
| *Considerations:* |
| |
| The `and()` step is a filter step that allows the traverser to pass if all of the provided traversals yield a result. |
| It follows the ternary boolean logic described in the <<gremlin-semantics-concepts,Ternary Boolean Logics>> section. |
| |
| *Exceptions* |
| |
| None |
| |
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/AndStep.java[source], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#and-step[reference] |
| |
| [[any-step]] |
| === any() |
| |
| *Description:* Filters array data from the Traversal Stream if any of the array's items match the supplied predicate. |
| |
| *Syntax:* `any(P predicate)` |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Start Step |Mid Step |Modulated |Domain |Range |
| |N |Y |N |`List`/`array`/`Iterable`/`Iterator` |`List`/`array`/`Iterable`/`Iterator` |
| |========================================================= |
| |
| *Arguments:* |
| |
| * `predicate` - The predicate to use to test each value in the array data. |
| |
| *Modulation:* |
| |
| None |
| |
| *Considerations:* |
| |
| Each value will be tested using the supplied predicate. Empty lists, null traversers, and non-list traversers will be |
| filtered out of the Traversal Stream. |
| |
| *Exceptions* |
| |
| * A GremlinTypeErrorException will be thrown if one occurs and no other value evaluates to true. |
| |
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/AnyStep.java[source], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#any-step[reference] |
| |
| [[as-step]] |
| === as() |
| |
| *Description:* Labels a step for later access by steps that make use of such labels. |
| |
| *Syntax:* `as(String stepLabel, String... stepLabels)` |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Start Step |Mid Step |Modulated |Domain |Range |
| |N |Y |N |`any` |`any` |
| |========================================================= |
| |
| *Arguments:* |
| |
| * `stepLabel` - The label to assign to the step. |
| * `stepLabels` - Additional labels to assign to the step. |
| |
| *Modulation:* |
| |
| None |
| |
| *Considerations:* |
| |
| The `as()` step is not a real step, but a "step modulator" similar to `by()` and `option()`. It allows labeling a step |
| for later access by steps like `select()` and `match()`. A step can have any number of labels associated with it, which |
| is useful for referencing the same step multiple times in a future step. |
| |
| *Exceptions* |
| |
| None |
| |
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java[source], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#as-step[reference] |
| |
| [[asBool-step]] |
| === asBool() |
| |
| *Description:* Parse the value of the incoming traverser as boolean. |
| |
| *Syntax:* `asBool()` |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Start Step |Mid Step |Modulated |Domain |Range |
| |N |Y |N |`Number`/`String`/`Boolean` |`Boolean` |
| |========================================================= |
| |
| *Arguments:* |
| |
| None |
| |
| Booleans are passed as is, numbers evaluate to `true` if non-zero, and `false` if zero or `NaN`. Strings only accept "true" or "false" (case-insensitive). |
| |
| *Exceptions* |
| |
| If the incoming traverser type is unsupported, a string other than "true" or "false", or `null`, then an `IllegalArgumentException` is thrown. |
| |
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AsBoolStep.java[source], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#asBool-step[reference] |
| |
| [[asDate-step]] |
| === asDate() |
| |
| *Description:* Parse the value of incoming traverser as date. Supported ISO-8601 strings and Unix time numbers. |
| |
| *Syntax:* `asDate()` |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Start Step |Mid Step |Modulated |Domain |Range |
| |N |Y |N |`any` |`any` |
| |========================================================= |
| |
| *Arguments:* |
| |
| None |
| |
| Incoming date remains unchanged. |
| |
| *Exceptions* |
| |
| * If the incoming traverser is a non-String/Number/Date value then an `IllegalArgumentException` will be thrown. |
| |
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AsDateStep.java[source], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#asDate-step[reference] |
| |
| [[asNumber-step]] |
| === asNumber() |
| |
| *Description:* converts the incoming traverser to the nearest parsable type if no argument is provided, or to the desired numerical type, based on the number token (`N`) provided. |
| |
| *Syntax:* `asNumber()` | `asNumber(GType typeToken)` |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Start Step |Mid Step |Modulated |Domain |Range |
| |N |Y |N |`Number`/`String` |`Number` |
| |========================================================= |
| |
| *Arguments:* |
| |
| * `typeToken` - The enum `GType` to denote the desired type to parse/cast to. |
| |
| If no type token is provided, the incoming number remains unchanged. |
| |
| *Exceptions* |
| |
| * If any overflow occurs during narrowing of types, then an `ArithmeticException` will be thrown. |
| * If the incoming string cannot be parsed into a valid number format, then a `NumberFormatException` will be thrown. |
| * If the incoming traverser is a non-String/Number (including `null`) value then an `IllegalArgumentException` will be thrown. |
| * If the supplied type token is not a number type, then an `IllegalArgumentException` will be thrown. |
| |
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AsNumberStep.java[source], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#asNumber-step[reference] |
| |
| [[asString-step]] |
| === asString() |
| |
| *Description:* Returns the value of incoming traverser as strings, or if `Scope.local` is specified, returns each element inside |
| incoming list traverser as string. |
| |
| *Syntax:* `asString()` | `asString(Scope scope)` |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Start Step |Mid Step |Modulated |Domain |Range |
| |N |Y |N |`any` |`String`/`List` |
| |========================================================= |
| |
| *Arguments:* |
| |
| * `scope` - Determines the type of traverser it operates on. Both scopes will operate on the level of individual traversers. |
| The `global` scope will operate on individual traverser, casting all (except `null`) to string. The `local` scope will behave like |
| `global` for everything except lists, where it will cast individual non-`null` elements inside the list into string and return a |
| list of string instead. |
| |
| *Exceptions* |
| |
| * If the incoming traverser is a `null` value then an `IllegalArgumentException` will be thrown. |
| |
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AsStringGlobalStep.java[source], |
| link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AsStringLocalStep.java[source (local)], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#asString-step[reference] |
| |
| [[barrier-step]] |
| === barrier() |
| |
| *Description:* Turns the lazy traversal pipeline into a bulk-synchronous pipeline. |
| |
| *Syntax:* `barrier()` | `barrier(int maxBarrierSize)` |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Start Step |Mid Step |Modulated |Domain |Range |
| |N |Y |N |`any` |`any` |
| |========================================================= |
| |
| *Arguments:* |
| |
| * `maxBarrierSize` - The maximum number of traversers that can be held in the barrier before being processed. |
| |
| *Modulation:* |
| |
| None |
| |
| *Considerations:* |
| |
| The `barrier()` step is useful in the following situations: |
| * When everything prior to `barrier()` needs to be executed before moving onto the steps after the `barrier()` (i.e., ordering). |
| * When "stalling" the traversal may lead to a "bulking optimization" in traversals that repeatedly touch many of the |
| same elements (i.e., optimizing). |
| |
| *Exceptions* |
| |
| None |
| |
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/NoOpBarrierStep.java[source], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#barrier-step[reference] |
| |
| [[both-step]] |
| === both() |
| |
| *Description:* Maps a vertex to its adjacent vertices given the edge labels. |
| |
| *Syntax:* `both(String... edgeLabels)` |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Start Step |Mid Step |Modulated |Domain |Range |
| |N |Y |N |`Vertex` |`Vertex` |
| |========================================================= |
| |
| *Arguments:* |
| |
| * `edgeLabels` - The edge labels to traverse. If no labels are provided, all edges are traversed. |
| |
| *Modulation:* |
| |
| None |
| |
| *Considerations:* |
| |
| The `both()` step is a vertex-centric step that traverses both incoming and outgoing edges from the current vertex to |
| adjacent vertices. It is equivalent to the union of `in()` and `out()`. |
| |
| *Exceptions* |
| |
| None |
| |
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/VertexStep.java[source], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#vertex-steps[reference] |
| |
| [[bothe-step]] |
| === bothE() |
| |
| *Description:* Maps a vertex to its incident edges given the edge labels. |
| |
| *Syntax:* `bothE(String... edgeLabels)` |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Start Step |Mid Step |Modulated |Domain |Range |
| |N |Y |N |`Vertex` |`Edge` |
| |========================================================= |
| |
| *Arguments:* |
| |
| * `edgeLabels` - The edge labels to traverse. If no labels are provided, all edges are traversed. |
| |
| *Modulation:* |
| |
| None |
| |
| *Considerations:* |
| |
| The `bothE()` step is a vertex-centric step that traverses both incoming and outgoing edges from the current vertex. It |
| is equivalent to the union of `inE()` and `outE()`. |
| |
| *Exceptions* |
| |
| None |
| |
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/VertexStep.java[source], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#vertex-steps[reference] |
| |
| [[bothv-step]] |
| === bothV() |
| |
| *Description:* Maps an edge to its incident vertices. |
| |
| *Syntax:* `bothV()` |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Start Step |Mid Step |Modulated |Domain |Range |
| |N |Y |N |`Edge` |`Vertex` |
| |========================================================= |
| |
| *Arguments:* |
| |
| None |
| |
| *Modulation:* |
| |
| None |
| |
| *Considerations:* |
| |
| The `bothV()` step is an edge-centric step that traverses to both the incoming and outgoing vertices of the current |
| edge. It is equivalent to the union of `inV()` and `outV()`. |
| |
| *Exceptions* |
| |
| None |
| |
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/EdgeVertexStep.java[source], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#vertex-steps[reference] |
| |
| [[branch-step]] |
| === branch() |
| |
| *Description:* Splits the traverser to all the specified traversals. |
| |
| *Syntax:* `branch(Traversal<?, M> branchTraversal)` | `branch(Function<Traverser<E>, M> function)` |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Start Step |Mid Step |Modulated |Domain |Range |
| |N |Y |`option()` |`any` |`any` |
| |========================================================= |
| |
| *Arguments:* |
| |
| * `branchTraversal` - The traversal to branch the traverser to. |
| * `function` - The function to branch the traverser to. |
| |
| *Modulation:* |
| |
| * `option()` - Specifies the branch options for the traverser. |
| |
| *Considerations:* |
| |
| The `branch()` step is a general step that splits the traverser to all the child traversals provided to it. It's the |
| basis for more robust steps like `choose()` and `union()`. The branch step is typically used with the `option()` step |
| to specify the branch options. |
| |
| *Exceptions* |
| |
| None |
| |
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/BranchStep.java[source], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#branch-step[reference] |
| |
| [[cap-step]] |
| === cap() |
| |
| *Description:* Iterates the traversal up to itself and emits the sideEffect referenced by the provided key. |
| |
| *Syntax:* `cap(String sideEffectKey, String... sideEffectKeys)` |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Start Step |Mid Step |Modulated |Domain |Range |
| |N |Y |N |`any` |`any` |
| |========================================================= |
| |
| *Arguments:* |
| |
| * `sideEffectKey` - The side-effect to emit. |
| * `sideEffectKeys` - Other side-effects to emit. |
| |
| *Modulation:* |
| |
| None |
| |
| *Considerations:* |
| |
| The `cap()` step is a barrier step that iterates the traversal up to itself and emits the sideEffect referenced by the |
| provided key. If multiple keys are provided, then a `Map<String,Object>` of sideEffects is emitted. |
| |
| *Exceptions* |
| |
| None |
| |
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/SideEffectCapStep.java[source], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#cap-step[reference] |
| |
| [[call-step]] |
| === call() |
| |
| *Description:* Provides support for provider-specific service calls. |
| |
| *Syntax:* `call()` | `call(String service, Map params)` | `call(String service, Traversal childTraversal)` | `call(String service, Map params, Traversal childTraversal)` |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Start Step |Mid Step |Modulated |Domain |Range |
| |Y |Y |`with()` |`any` |`any` |
| |========================================================= |
| |
| *Arguments:* |
| |
| * `service` - The name of the service call. |
| * `params` - A collection of static parameters relevant to the particular service call. Keys and values can be any |
| type currently supported by the Gremlin type system. |
| * `childTraversal` - A traversal used to dynamically build at query time a collection of parameters relevant to the service |
| call. |
| |
| *Modulation:* |
| |
| * `with(key, value)` - Sets an additional static parameter relevant to the service call. Key and value can be any |
| type currently supported by the Gremlin type system. |
| * `with(key, Traversal)` - Sets an additional dynamic parameter relevant to the service call. Key can be any |
| type currently supported by the Gremlin type system. |
| |
| How static and dynamic parameters are merged is a detail left to the provider implementation. The reference implementation |
| (`CallStep`) uses effectively a "left to right" merge of the parameters - it starts with the static parameter `Map` |
| argument, then merges in the parameters from the dynamic `Traversal` argument, then merges in each `with` modulation |
| one by one in the order they appear. |
| |
| Service calls in the reference implementation can be specified as `Start` (start of traversal), `Streaming` |
| (mid-traversal flat map step), and `Barrier` (mid-traversal barrier step). Furthermore, the `Barrier` type can be |
| all-at-once or with a maximum chunk size. A single service can support more than one of these modes, and if it does, |
| must provide semantics for how to configure the mode at query time via parameters. |
| |
| Providers using the reference implementation to support service call with need to provide a `ServiceFactory` for each |
| named service that can create `Service` instances for execution during traversal. The `ServiceFactory` is a singleton |
| that is registered with the `ServiceRegistry` located on the provider `Graph`. The `Service` instance is local to |
| each traversal, although providers can choose to re-use instances across traversals provided there is no state. |
| |
| *Considerations:* |
| |
| Providers using the reference implementation can return `Traverser` output or raw value output - the `CallStep` will |
| handle either case appropriately. In the case of a `Streaming` service, where there is exactly one input to each |
| call, the reference implementation can preserve `Path` information by splitting the input `Traverser` when receiving |
| raw output from the call. In the case of `Barrier` however, it is the responsiblity of the `Service` to preserve |
| `Path` information by producing its own `Traversers` as output, since the `CallStep` cannot match input and ouput |
| across a barrier. The ability to split input `Traversers` and generate output is provided by the reference |
| implementation's `ServiceCallContext` object, which is supplied to the `Service` during execution. |
| |
| There are three execution methods in the reference implementation service call API: |
| |
| * `execute(ServiceCallContext, Map)` - execute a service call to start a traversal |
| * `execute(ServiceCallContext, Traverser, Map)` - execute a service call mid-traversal streaming (one input) |
| * `execute(ServiceCallContext, TraverserSet, Map)` - execute a service call mid-traversal barrier |
| |
| The Map is the merged collection of all static and dynamic parameters. In the case of `Barrier` execution, notice |
| that there is one `Map` for many input. Since the `call()` API support dynamic parameters, this implies that all |
| input must reduce to the same set of parameters for `Barrier` execution. In the reference implementation, if more |
| than one parameter set is detected, this will cause an execution and the traversal will halt. Providers that |
| implement their own version of a call operation may decide on other strategies to handle this case - for example |
| it may be sensible to group traversers by Map in the case where multiple parameter sets are detected. |
| |
| The no-arg version of the `call()` API is meant to be a directory service and should only be used to start a traversal. |
| The reference implementation provides a default version, with will produce a list of service names or a service |
| description if run with `verbose=true`. Providers using the own implementation of the call operation must provide their |
| own directory listing service with the service name `"--list"`. |
| |
| *Exceptions* |
| |
| * If a named service does not support the execution mode implied by the traversal, for example, using a `Streaming` or |
| `Barrier` step as a traversal source, this will result in an `UnsupportedOperationException`. |
| * As mentioned above, dynamic property parameters (`Traversals`) that reduce to more than one property set for a chunk |
| of input is not supported in the reference implementation and will result in an `UnsupportedOperationException`. |
| * Use of the reference implementation's built-in directory service - `call()` or `call("--list")` - mid-traversal |
| will result in an `UnsupportedOperationException`. |
| |
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/CallStep.java[CallStep], |
| link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/service/Service.java[Service], |
| link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/service/ServiceRegistry.java[ServiceRegistry], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#call-step[reference] |
| |
| [[choose-step]] |
| === choose() |
| |
| *Description:* A branch step that routes the traverser to different paths based on a choice criterion. |
| |
| *Syntax:* `choose(Traversal|T choice)` | `choose(Traversal|P choice, Traversal trueChoice)` |`choose(Traversal|P choice, Traversal trueChoice, Traversal falseChoice)` |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Start Step |Mid Step |Modulated |Domain |Range |
| |N |Y |Y |`any` |`any` |
| |========================================================= |
| |
| *Arguments:* |
| |
| * `choice` - A `Traversal`, or `T` that produces a value used to determine which option to take. In the `if-then` forms, this value may be a `P` to determine `true` or `false`. |
| * `trueChoice` - The traversal to take if the predicate traversal returns a value (has a next element). |
| * `falseChoice` - The traversal to take if the predicate traversal returns no value (has no next element). |
| |
| *Modulation:* |
| |
| * `option(pickToken, traversalOption)` - Adds a traversal option to the `choose` step. The `pickToken` is matched |
| against the result of the choice traversal. The `pickToken` may be a literal value, a predicate `P` or a `Pick` enum |
| value. `Traversal` is not allowed as a `pickToken` here and will lead to `IllegalArgumentException`. If a match is |
| found, the traverser is routed to the corresponding `traversalOption`. |
| |
| *Considerations:* |
| |
| The `choose()` step is a branch step that routes the traverser to different paths based on a choice criterion. There are |
| two main forms of the `choose()` step: |
| |
| 1. *if-then form*: `choose(predicate, trueChoice, falseChoice)` - If the predicate traversal or `P` returns a value |
| (has a next element), the traverser is routed to the trueChoice traversal. Otherwise, it is routed to the falseChoice |
| traversal. If the predicate is unproductive or if the falseChoice is not specified, then the traverser passes through. |
| |
| 2. *switch form*: `choose(choice).option(pickValue, resultTraversal)` - The choice which may be a `Traversal` or |
| `T` produces a value that is matched against the pickValue of each option. If a match is found, the traverser is routed |
| to the corresponding resultTraversal and no further matches are attempted. If no match is found then the traverser |
| passes through by default or can be matched on `Pick.none`. If the choiceTraversal is unproductive, then the traverser |
| passes through by default or can be matched on `Pick.unproductive`. |
| |
| `choose` does not allow more than one traversal to be assigned to a single `Pick`. The first `Pick` assigned via |
| `option` is the one that will be used, similar to how the first pickValue match that is found is used. |
| |
| The `choose()` step ensures that only one option is selected for each traverser, unlike other branch steps like |
| `union()` that can route a traverser to multiple paths. As it is like `union()`, note that each `option` stream will |
| behave like one: |
| |
| [gremlin-groovy,modern] |
| ---- |
| g.V().union(__.has("name", "vadas").values('age').fold(), __.has('name',neq('vadas')).values('name').fold()) |
| g.V().choose(__.has("name", "vadas"), __.values('age').fold(), __.values('name').fold()) |
| ---- |
| |
| *Exceptions* |
| |
| * `IllegalArgumentException` - If `Pick.any` is used as an option token, as only one option per traverser is allowed. |
| |
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/ChooseStep.java[source], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#choose-step[reference] |
| |
| [[combine-step]] |
| === combine() |
| |
| *Description:* Appends one list to the other and returns the result to the Traversal Stream. |
| |
| *Syntax:* `combine(Object values)` |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Start Step |Mid Step |Modulated |Domain |Range |
| |N |Y |N |`array`/`Iterable` |`List` |
| |========================================================= |
| |
| *Arguments:* |
| |
| * `values` - A list of items (as an Iterable or an array) or a traversal that will produce a list of items. |
| |
| *Modulation:* |
| |
| None |
| |
| *Considerations:* |
| |
| A list is returned after the combine operation is applied so duplicates are allowed. `Merge` can be used instead if |
| duplicates aren't wanted. This step only applies to list types which means that non-iterable types (including null) |
| will cause exceptions to be thrown. |
| |
| *Exceptions* |
| |
| * If the incoming traverser isn't a list (array or Iterable) then an `IllegalArgumentException` will be thrown. |
| * If the argument doesn't resolve to a list (array or Iterable) then an `IllegalArgumentException` will be thrown. |
| |
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/CombineStep.java[source], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#combine-step[reference], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#merge-step[merge() reference] |
| |
| [[coin-step]] |
| === coin() |
| |
| *Description:* Filters traversers from the Traversal Stream based on a biased coin toss. |
| |
| *Syntax:* `coin(double probability)` |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Start Step |Mid Step |Modulated |Domain |Range |
| |N |Y |N |`any` |`any` |
| |========================================================= |
| |
| *Arguments:* |
| |
| * `probability` - The probability (between 0.0 and 1.0) that the traverser will pass through the filter. |
| |
| *Modulation:* |
| |
| None |
| |
| *Considerations:* |
| |
| Each traverser is subject to a random filter based on the provided probability. A probability of 0.0 means no |
| traversers pass through, while a probability of 1.0 means all traversers pass through. |
| |
| *Exceptions* |
| |
| None |
| |
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/CoinStep.java[source], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#coin-step[reference] |
| |
| [[concat-step]] |
| === concat() |
| |
| *Description:* Concatenates the incoming String traverser with the input String arguments, and return the joined String. |
| |
| *Syntax:* `concat()` | `concat(String... concatStrings)` | `concat(Traversal concatTraveral, Traversal... otherConcatTraverals)` |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Start Step |Mid Step |Modulated |Domain |Range |
| |N |Y |N |`String` |`String` |
| |========================================================= |
| |
| *Arguments:* |
| |
| * `concatStrings` - Varargs of `String`. If one or more String values are provided, they will be concatenated together |
| with the incoming traverser. If no argument is provided, the String value from the incoming traverser is returned. |
| * `concatTraveral` - A `Traversal` whose must value resolve to a `String`. The first result returned from the traversal will |
| be concatenated with the incoming traverser. |
| * `otherConcatTraverals` - Varargs of `Traversal`. Each `Traversal` value must resolve to a `String`. The first result |
| returned from each traversal will be concatenated with the incoming traverser and the previous traversal arguments. |
| |
| Any `null` String values will be skipped when concatenated with non-`null` String values. If two `null` value are |
| concatenated, the `null` value will be propagated and returned. |
| |
| *Exceptions* |
| |
| * If the incoming traverser is a non-String value then an `IllegalArgumentException` will be thrown. |
| |
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ConcatStep.java[source], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#concat-step[reference] |
| |
| [[dateAdd-step]] |
| === dateAdd() |
| |
| *Description:* Increase value of input Date. |
| |
| *Syntax:* `dateAdd(DT dateToken, Integer value)` |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Start Step |Mid Step |Modulated |Domain |Range |
| |N |Y |N |`Date` |`Date` |
| |========================================================= |
| |
| *Arguments:* |
| |
| * `dateToken` - Date token enum. Supported values `second`, `minute`, `hour`, `day`. |
| * `value` - The number of units, specified by the DT Token, to add to the incoming values. May be negative for subtraction. |
| |
| *Exceptions* |
| |
| * If the incoming traverser is a non-Date value then an `IllegalArgumentException` will be thrown. |
| |
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/DateAddStep.java[source], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#dateAdd-step[reference] |
| |
| [[dateDiff-step]] |
| === dateDiff() |
| |
| *Description:* Returns the difference between two Dates in epoch time. |
| |
| *Syntax:* `dateDiff(Date value)` | `dateDiff(Traversal dateTraversal)` |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Start Step |Mid Step |Modulated |Domain |Range |
| |N |Y |N |`Date` |`Date` |
| |========================================================= |
| |
| *Arguments:* |
| |
| * `value` - Date for subtraction. |
| * `dateTraversal` - The `Traversal` value must resolve to a `Date`. The first result returned from the traversal will be |
| subtracted with the incoming traverser. |
| |
| If argument resolves as `null` then incoming date will not be changed. |
| |
| *Exceptions* |
| |
| * If the incoming traverser is a non-Date value then an `IllegalArgumentException` will be thrown. |
| |
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/DateDiffStep.java[source], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#dateDiff-step[reference] |
| |
| [[dedup-step]] |
| === dedup() |
| |
| *Description:* Removes repeatedly seen results from the Traversal Stream. |
| |
| *Syntax:* `dedup()` | `dedup(String... labels)` | `dedup(Scope scope, String... labels)` |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Start Step |Mid Step |Modulated |Domain |Range |
| |N |Y |`by()` |`any` |`any` |
| |========================================================= |
| |
| *Arguments:* |
| |
| * `scope` - Determines the scope in which `dedup` is applied. |
| The `global` scope will drop duplicate values across the global stream of traversers. The `local` scope operates at the |
| individual traverser level, and will remove duplicate values from within a collection. |
| |
| * `labels` - If `dedup()` is provided a list of labels, then it will ensure that the de-duplication |
| is not with respect to the current traverser object, but to the path history of the traverser. |
| |
| For Example: |
| |
| [source,groovy] |
| ---- |
| g.V().as('a').out('created').as('b').in('created').as('c'). |
| dedup('a','b').select('a','b','c') |
| ---- |
| |
| will filter out any such `a` and `b` pairs which have previously been seen. |
| |
| *Modulation:* |
| |
| * `by()` - Performs dedup according to the property specified in the by modulation. For example: |
| `g.V().dedup().by("name")` will filter out vertices with duplicate names. |
| |
| *Considerations:* |
| |
| * There is no guarantee that ordering of results will be preserved across a dedup step. |
| * There is no guarantee which element is selected as the survivor when filtering duplicates. |
| |
| For example, given a graph with the following three vertices: |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |name |age |
| |Alex |38 |
| |Bob |45 |
| |Chloe |38 |
| |========================================================= |
| |
| and the traversal of: |
| |
| [source,groovy] |
| ---- |
| g.V().order().by("name", Order.asc). |
| dedup().by("age").values("name") |
| ---- |
| |
| can return any of: |
| |
| `["Alex", "Bob"]`, `["Bob", "Alex"]`, `["Bob", "Chloe"]`, or `["Chloe", "Bob"]` |
| |
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/DedupGlobalStep.java[source], |
| link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/DedupLocalStep.java[source (local)], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#dedup-step[reference] |
| |
| [[difference-step]] |
| === difference() |
| |
| *Description:* Adds the difference of two lists to the Traversal Stream. |
| |
| *Syntax:* `difference(Object values)` |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Start Step |Mid Step |Modulated |Domain |Range |
| |N |Y |N |`array`/`Iterable` |`Set` |
| |========================================================= |
| |
| *Arguments:* |
| |
| * `values` - A list of items (as an Iterable or an array) or a `Traversal` that will produce a list of items. |
| |
| *Modulation:* |
| |
| None |
| |
| *Considerations:* |
| |
| Set difference (`A-B`) is an ordered operation. The incoming traverser is treated as `A` and the provided argument is |
| treated as `B`. A set is returned after the difference operation is applied so there won't be duplicates. This step only |
| applies to list types which means that non-iterable types (including null) will cause exceptions to be thrown. |
| |
| *Exceptions* |
| |
| * If the incoming traverser isn't a list (array or Iterable) then an `IllegalArgumentException` will be thrown. |
| * If the argument doesn't resolve to a list (array or Iterable) then an `IllegalArgumentException` will be thrown. |
| |
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/DifferenceStep.java[source], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#difference-step[reference] |
| |
| [[disjunct-step]] |
| === disjunct() |
| |
| *Description:* Adds the disjunct set to the Traversal Stream. |
| |
| *Syntax:* `disjunct(Object values)` |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Start Step |Mid Step |Modulated |Domain |Range |
| |N |Y |N |`array`/`Iterable` |`Set` |
| |========================================================= |
| |
| *Arguments:* |
| |
| * `values` - A list of items (as an Iterable or an array) or a `Traversal` that will produce a list of items. |
| |
| *Modulation:* |
| |
| None |
| |
| *Considerations:* |
| |
| A set is returned after the disjunct operation is applied so there won't be duplicates. This step only applies to list |
| types which means that non-iterable types (including null) will cause exceptions to be thrown. |
| |
| *Exceptions* |
| |
| * If the incoming traverser isn't a list (array or Iterable) then an `IllegalArgumentException` will be thrown. |
| * If the argument doesn't resolve to a list (array or Iterable) then an `IllegalArgumentException` will be thrown. |
| |
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/DisjunctStep.java[source], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#disjunct-step[reference] |
| |
| [[element-step]] |
| === element() |
| |
| *Description:* Traverse from `Property` to its `Element`. |
| |
| *Syntax:* `element()` |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Start Step |Mid Step |Modulated |Domain |Range |
| |N |Y |N |`Property` |`Element` |
| |========================================================= |
| |
| *Arguments:* |
| |
| None |
| |
| *Modulation:* |
| |
| None |
| |
| [[format-step]] |
| === format() |
| |
| *Description:* a mid-traversal step which will handle result formatting to string values. |
| |
| *Syntax:* `format(String formatString)` |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Start Step |Mid Step |Modulated |Domain |Range |
| |N |Y |`by()` |`any` |`String` |
| |========================================================= |
| |
| *Arguments:* |
| |
| * `formatString` - Variables can be represented with `%{variable_name}` notation. |
| Positional arguments can be used as `%{_}` token. Can be used multiple times. |
| The variable values are used in the order that the first one will be found: Element properties, then Scope values. |
| If value for some variable was not found, then the result is filtered out. |
| |
| *Exceptions* |
| |
| None |
| |
| *Modulation:* |
| |
| * `by()` - Used to inject positional argument. For example: |
| `g.V().format("%{name} has %{_} connections").by(bothE().count())`. |
| |
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/FormatStep.java[source], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#format-step[reference] |
| |
| [[group-step]] |
| === group() |
| |
| *Description:* Groups objects in the traversal stream by a key and applies a reducing operation to the grouped values. |
| |
| *Syntax:* `group()` | `group(String sideEffectKey)` |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Start Step |Mid Step |Modulated |Domain |Range |
| |N |Y |`by()` |`any` |`any` |
| |========================================================= |
| |
| *Arguments:* |
| |
| * `sideEffectKey` - The name of the side-effect key that will hold the aggregated grouping. When provided, the step |
| operates as a side-effect barrier step and passes the traverser to the next step unchanged. If `sideEffectKey` is |
| omitted, the step operates as a reducing barrier step, and a single traverser containing the computed map is passed to |
| the next step. |
| |
| *Modulation:* |
| |
| * `by()` - The first `by()` determines the key for grouping. The second `by()` determines the value to be reduced for |
| each group. If no key `by()` is provided, the object itself is used as the key. If no value `by()` is provided, the |
| objects are collected into a list. |
| |
| *Considerations:* |
| |
| The `group()` step can be used as both a reducing barrier step and a side-effect step. As a reducing barrier step (no |
| side-effect key), it returns a `Map<Object, Object>` where keys are the grouping criteria and values are the reduced |
| results. As a side-effect step, it stores the grouping in a side-effect and passes the traverser to the next step |
| unchanged. In both forms, this step is a barrier and must fully iterate the traversal before returning any results. |
| |
| *Exceptions* |
| |
| * If more than 2 `by()` modulators are provided, an `IllegalStateException` will be thrown. |
| |
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroupStep.java[source], |
| link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupSideEffectStep.java[source (sideEffect)], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#group-step[reference] |
| |
| [[groupcount-step]] |
| === groupCount() |
| |
| *Description:* Counts the number of times a particular object has been part of a traversal, returning a `Map` where the |
| object is the key and the value is the count. |
| |
| *Syntax:* `groupCount()` | `groupCount(String sideEffectKey)` |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Start Step |Mid Step |Modulated |Domain |Range |
| |N |Y |`by()` |`any` |`any` |
| |========================================================= |
| |
| *Arguments:* |
| |
| * `sideEffectKey` - The name of the side-effect key that will hold the aggregated grouping. When provided, the step |
| operates as a side-effect step and passes the traverser to the next step unchanged. |
| |
| *Modulation:* |
| |
| * `by()` - Determines how to transform the object before counting. If not specified, the object itself is used as the |
| key. |
| |
| *Considerations:* |
| |
| The `groupCount()` step can be used as both a map step and a side-effect step. As a map step, it returns a |
| `Map<Object, Long>` with the counted objects as keys and their counts as values. As a side-effect step, it stores the |
| counts in a side-effect and passes the traverser to the next step unchanged. Note that both the map and side-effect |
| forms of this step are barriers that must fully iterate the traversal before returning any results. |
| |
| *Exceptions* |
| |
| * If multiple `by()` modulators are provided, an `IllegalStateException` will be thrown. |
| |
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroupCountStep.java[source], |
| link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupCountSideEffectStep.java[source (sideEffect)], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#groupcount-step[reference] |
| |
| [[length-step]] |
| === length() |
| |
| *Description:* Returns the length of the incoming string or list, if `Scope.local` is specified, returns |
| the length of each string elements inside incoming list traverser. |
| |
| *Syntax:* `length()` | `length(Scope scope)` |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Start Step |Mid Step |Modulated |Domain |Range |
| |N |Y |N |`String`/`array`/`Iterable` |`Integer`/`List` |
| |========================================================= |
| |
| *Arguments:* |
| |
| * `scope` - Determines the type of traverser it operates on. Both scopes will operate on the level of individual traversers. |
| The `global` scope will operate on individual string traverser. The `local` scope will operate on list traverser with string elements inside. |
| |
| Null values from the incoming traverser are not processed and remain as null when returned. |
| |
| *Exceptions* |
| |
| * For `Scope.global` or parameterless function calls, if the incoming traverser is a non-String value then an `IllegalArgumentException` will be thrown. |
| * For `Scope.local`, if the incoming traverser is not a string or a list of strings then an `IllegalArgumentException` will be thrown. |
| |
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/LengthGlobalStep.java[source], |
| link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/LengthLocalStep.java[source (local)], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#length-step[reference] |
| |
| [[local-step]] |
| === local() |
| |
| *Description:* Executes the provided traversal in an object-local manner. |
| |
| *Syntax:* `local(Traversal localTraversal)` |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Start Step |Mid Step |Modulated |Domain |Range |
| |N |Y |N |`any` |`any` |
| |========================================================= |
| |
| *Arguments:* |
| |
| * `localTraversal` - The traversal that processes each single-object traverser individually. |
| |
| *Modulation:* |
| |
| None |
| |
| *Considerations:* |
| |
| The `local()` step enforces object-local execution. As a branching step with local children, it implements strict lazy |
| evaluation by passing a single traverser at a time to the local traversal (bulk of exactly one, if bulking is supported) |
| and resetting the traversal to clean state between executions. |
| |
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/LocalStep.java[source], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#local-step[reference] |
| |
| [[intersect-step]] |
| === intersect() |
| |
| *Description:* Adds the intersection to the Traversal Stream. |
| |
| *Syntax:* `intersect(Object values)` |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Start Step |Mid Step |Modulated |Domain |Range |
| |N |Y |N |`array`/`Iterable` |`Set` |
| |========================================================= |
| |
| *Arguments:* |
| |
| * `values` - A list of items (as an Iterable or an array) or a `Traversal` that will produce a list of items. |
| |
| |
| *Modulation:* |
| |
| None |
| |
| *Considerations:* |
| |
| A set is returned after the intersect operation is applied so there won't be duplicates. This step only applies to list |
| types which means that non-iterable types (including null) will cause exceptions to be thrown. |
| |
| *Exceptions* |
| |
| * If the incoming traverser isn't a list (array or Iterable) then an `IllegalArgumentException` will be thrown. |
| * If the argument doesn't resolve to a list (array or Iterable) then an `IllegalArgumentException` will be thrown. |
| |
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/IntersectStep.java[source], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#intersect-step[reference] |
| |
| [[conjoin-step]] |
| === conjoin() |
| |
| *Description:* Joins every element in a list together into a String. |
| |
| *Syntax:* `conjoin(String delimiter)` |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Start Step |Mid Step |Modulated |Domain |Range |
| |N |Y |N |`array`/`Iterable` |`String` |
| |========================================================= |
| |
| *Arguments:* |
| |
| * `delimiter` - A delimiter to use to join the elements together. Can't be null. |
| |
| *Modulation:* |
| |
| None |
| |
| *Considerations:* |
| |
| Every element in the list (except `null`) is converted to a String. Null values are ignored. The delimiter is inserted |
| between neighboring elements to form the final result. This step only applies to list types which means that |
| non-iterable types (including `null`) will cause exceptions to be thrown. |
| |
| *Exceptions* |
| |
| * If the incoming traverser isn't a list (array or Iterable) then an `IllegalArgumentException` will be thrown. |
| * If the argument doesn't resolve to a list (array or Iterable) then an `IllegalArgumentException` will be thrown. |
| |
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ConjoinStep.java[source], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#conjoin-step[reference] |
| |
| [[lTrim-step]] |
| === lTrim() |
| |
| *Description:* Returns a string with leading whitespace removed. |
| |
| *Syntax:* `lTrim()` | `lTrim(Scope scope)` |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Start Step |Mid Step |Modulated |Domain |Range |
| |N |Y |N |`String`/`array`/`Iterable` |`String`/`List` |
| |========================================================= |
| |
| *Arguments:* |
| |
| * `scope` - Determines the type of traverser it operates on. Both scopes will operate on the level of individual traversers. |
| The `global` scope will operate on individual string traverser. The `local` scope will operate on list traverser with string elements inside. |
| |
| Null values from the incoming traverser are not processed and remain as null when returned. |
| |
| *Exceptions* |
| |
| * For `Scope.global` or parameterless function calls, if the incoming traverser is a non-String value then an `IllegalArgumentException` will be thrown. |
| * For `Scope.local`, if the incoming traverser is not a string or a list of strings then an `IllegalArgumentException` will be thrown. |
| |
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/LTrimGlobalStep.java[source], |
| link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/LTrimLocalStep.java[source (local)], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#lTrim-step[reference] |
| |
| [[merge-step]] |
| === merge() |
| |
| *Description:* Adds the union of two sets (or two maps) to the Traversal Stream. |
| |
| *Syntax:* `merge(Object values)` |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Start Step |Mid Step |Modulated |Domain |Range |
| |N |Y |N |`array`/`Iterable`/`Map` |`Set`/`Map` |
| |========================================================= |
| |
| *Arguments:* |
| |
| * `values` - A list of items (as an `Iterable` or an array), a `Map`, or a `Traversal` that will produce a list of items. |
| |
| *Modulation:* |
| |
| None |
| |
| *Considerations:* |
| |
| For iterable types, a set is returned after the merge operation is applied so there won't be duplicates. For maps, if |
| both maps contain the same key then the value yielded from the argument will be the value put into the merged map. This |
| step only applies to list types or maps which means that other non-iterable types (including null) will cause exceptions |
| to be thrown. |
| |
| *Exceptions* |
| |
| * If the incoming traverser isn't a list (array or Iterable) or map then an `IllegalArgumentException` will be thrown. |
| * If the argument doesn't resolve to a list (array or Iterable) or map then an `IllegalArgumentException` will be thrown. |
| |
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MergeStep.java[source], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#merge-step[reference] |
| |
| [[merge-e-step]] |
| === mergeE() |
| |
| *Description:* Provides upsert-like functionality for edges. |
| |
| *Syntax:* `mergeE()` | `mergeE(Map searchCreate)` | `mergeE(Traversal searchCreate)` |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Start Step |Mid Step |Modulated |Domain |Range |
| |Y |Y |`option()` |`Map`/`Vertex` |`Edge` |
| |========================================================= |
| |
| *Arguments:* |
| |
| * `searchCreate` - A `Map` used to match an `Edge` and if not found will be the default set of data to create the new one. |
| * `onCreate` - A `Map` used to specify additional existence criteria and/or properties not already specified in `searchCreate`. |
| * `onMatch` - A `Map` used to update the `Edge` that is found using the `searchCreate` criteria. |
| * `outV` - A `Vertex` that will be late-bound into the `searchCreate` and `onCreate` `Maps` for the `Direction.OUT` key, |
| or else another `Map` used to search for that `Vertex` |
| * `inV` - A `Vertex` that will be late-bound into the `searchCreate` and `onCreate` `Maps` for the `Direction.IN` key, |
| or else another `Map` used to search for that `Vertex` |
| |
| The `searchCreate` and `onCreate` `Map` instances must consist of any combination of: |
| |
| * `T` - `id`, `label` |
| * `Direction` - `IN` or `to`, `OUT` or `from` |
| * Arbitrary `String` keys (which are assumed to be vertex properties). |
| |
| The `onMatch` `Map` instance only allows for `String` keys as the `id` and `label` of a `Vertex` are immutable as are |
| the incident vertices. Values for these valid keys that are `null` will be treated according to the semantics of the |
| `addE()` step. |
| |
| The `Map` that is used as the argument for `searchCreate` may be assigned from the incoming `Traverser` for the no-arg |
| `mergeE()`. If `mergeE(Map)` is used, then it will override the incoming `Traverser`. If `mergeE(Traversal)` is used, |
| the `Traversal` argument must resolve to a `Map` and it would also override the incoming Traverser. The `onCreate` and |
| `onMatch` arguments are assigned via modulation as described below. |
| |
| If `onMatch` is triggered the `Traverser` becomes the matched `Edge`, but the traversal still must return a `Map` |
| instance to be applied. `Null` is considered semantically equivalent to an empty `Map`. |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Event |Empty `Map` (or Null) |
| |Search |Matches all edges |
| |Create |New edge with defaults |
| |Update |No update to matched edge |
| |========================================================= |
| |
| If `T.id` is used for `searchCreate` or `onCreate`, it may be ignored for edge creation if the `Graph` does not |
| support user supplied identifiers. `onCreate` inherits from `searchCreate` - values for `T.id`, `T.label`, and |
| `Direction.OUT/IN` do not need to be specified twice. Additionally, `onCreate` cannot override values in `searchCreate` |
| (i.e. `if (exists(x)) return(x) else create(y)` is not supported). |
| |
| *Modulation:* |
| |
| * `option(Merge, Map)` - Sets the `onCreate` or `onMatch` arguments directly. |
| * `option(Merge, Traversal)` - Sets the `onCreate` or `onMatch` arguments dynamically where the `Traversal` must |
| resolve to a `Map`. |
| * `option(Merge.outV/inV)` can also accept a `Traversal` that resolves to a `Vertex`, allowing `mergeE` to be combined |
| with `mergeV` via a `select` operation. |
| |
| *Exceptions* |
| |
| * `Map` arguments are validated for their keys resulting in exception if they do not meet requirements defined above. |
| * Use of `T.label` should always have a value that is a `String`. |
| * If `T.id`, `T.label`, and/or `Direction.IN/OUT` are specified in `searchCreate`, they cannot be overriden in `onCreate`. |
| * For late binding of the from and to vertices, `Direction.OUT` must be set to `Merge.outV` and `Direction.IN` must |
| be set to `Merge.inV`. Other combinations are not allowed and will result in exception. |
| |
| *Considerations:* |
| |
| * `mergeE()` (i.e. the zero-arg overload) can only be used mid-traversal. It is not a start step. |
| * As is common to Gremlin, it is expected that `Traversal` arguments may utilize `sideEffect()` steps. |
| |
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MergeEdgeStep.java[source], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#mergee-step[reference] |
| |
| [[merge-v-step]] |
| === mergeV() |
| |
| *Description:* Provides upsert-like functionality for vertices. |
| |
| *Syntax:* `mergeV()` | `mergeV(Map searchCreate)` | `mergeV(Traversal searchCreate)` |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Start Step |Mid Step |Modulated |Domain |Range |
| |Y |Y |`option()` |`Map` |`Vertex` |
| |========================================================= |
| |
| *Arguments:* |
| |
| * `searchCreate` - A `Map` used to match a `Vertex` and if not found will be the default set of data to create the new one. |
| * `onCreate` - A `Map` used to specify additional existence criteria and/or properties not already specified in `searchCreate`. |
| * `onMatch` - A `Map` used to update the `Vertex` that is found using the `searchCreate` criteria. |
| |
| The `searchCreate` and `onCreate` `Map` instances must consists of any combination of `T.id`, `T.label`, or arbitrary |
| `String` keys (which are assumed to be vertex properties). The `onMatch` `Map` instance only allows for `String` keys |
| as the `id` and `label` of a `Vertex` are immutable. `null` Values for these valid keys are not allowed. |
| |
| The `Map` that is used as the argument for `searchCreate` may be assigned from the incoming `Traverser` for the no-arg |
| `mergeV()`. If `mergeV(Map)` is used, then it will override the incoming `Traverser`. If `mergeV(Traversal)` is used, |
| the `Traversal` argument must resolve to a `Map` and it would also override the incoming Traverser. The `onCreate` and |
| `onMatch` arguments are assigned via modulation as described below. |
| |
| If `onMatch` is triggered the `Traverser` becomes the matched `Vertex`, but the traversal still must return a `Map` |
| instance to be applied. `Null` is considered semantically equivalent to an empty `Map`. |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Event |Empty `Map` (or Null) |
| |Search |Matches all vertices |
| |Create |New vertex with defaults |
| |Update |No update to matched vertex |
| |========================================================= |
| |
| If `T.id` is used for `searchCreate` or `onCreate`, it may be ignored for vertex creation if the `Graph` does not |
| support user supplied identifiers. `onCreate` inherits from `searchCreate` - values for `T.id`, `T.label` do not need |
| to be specified twice. Additionally, `onCreate` cannot override values in `searchCreate` |
| (i.e. `if (exists(x)) return(x) else create(y)` is not supported). |
| |
| *Modulation:* |
| |
| * `option(Merge, Map)` - Sets the `onCreate` or `onMatch` arguments directly. |
| * `option(Merge, Traversal)` - Sets the `onCreate` or `onMatch` arguments dynamically where the `Traversal` must |
| resolve to a `Map`. |
| |
| *Exceptions* |
| |
| * `Map` arguments are validated for their keys resulting in exception if they do not meet requirements defined above. |
| * Use of `T.label` should always have a value that is a `String`. |
| * If `T.id` and/or `T.label` are specified in `searchCreate`, they cannot be overriden in `onCreate`. |
| |
| *Considerations:* |
| |
| * `mergeV()` (i.e. the zero-arg overload) can only be used mid-traversal. It is not a start step. |
| * As is common to Gremlin, it is expected that `Traversal` arguments may utilize `sideEffect()` steps. |
| |
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MergeVertexStep.java[source], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#mergev-step[reference] |
| |
| [[none-step]] |
| === none() |
| |
| *Description:* Filters array data from the traversal stream if none of the array's items match the supplied predicate. |
| |
| *Syntax:* `none(P predicate)` |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Start Step |Mid Step |Modulated |Domain |Range |
| |N |Y |N |`List`/`array`/`Iterable`/`Iterator` |`List`/`array`/`Iterable`/`Iterator` |
| |========================================================= |
| |
| *Arguments:* |
| |
| * `predicate` - The predicate used to test each value in the array data. |
| |
| *Modulation:* |
| |
| None |
| |
| *Considerations:* |
| |
| Each value will be tested using the supplied predicate. Empty lists always pass through and null/non-list traversers |
| will be filtered out of the traversal stream. |
| |
| *Exceptions* |
| |
| * A GremlinTypeErrorException will be thrown if one occurs and no other value evaluates to true. |
| |
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/NoneStep.java[source], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#none-step[reference] |
| |
| [[product-step]] |
| === product() |
| |
| *Description:* Adds the cartesian product to the Traversal Stream. |
| |
| *Syntax:* `product(Object values)` |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Start Step |Mid Step |Modulated |Domain |Range |
| |N |Y |N |`array`/`Iterable` |`List(List)` |
| |========================================================= |
| |
| *Arguments:* |
| |
| * `values` - A list of items (as an `Iterable` or an array) or a `Traversal` that will produce a list of items. |
| |
| *Modulation:* |
| |
| None |
| |
| *Considerations:* |
| |
| A list of lists is returned after the product operation is applied with the inner list being a result pair. This step only |
| applies to list types which means that non-iterable types (including null) will cause exceptions to be thrown. |
| |
| *Exceptions* |
| |
| * If the incoming traverser isn't a list (array or Iterable) then an `IllegalArgumentException` will be thrown. |
| * If the argument doesn't resolve to a list (array or Iterable) then an `IllegalArgumentException` will be thrown. |
| |
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ProductStep.java[source], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#product-step[reference] |
| |
| [[project-step]] |
| === project() |
| |
| *Description:* Projects the current object in the stream into a `Map` that is keyed by the provided labels. |
| |
| *Syntax:* `project(String projectKey, String... otherProjectKeys)` |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Start Step |Mid Step |Modulated |Domain |Range |
| |N |Y |`by()` |`any` |`Map<String, Object>` |
| |========================================================= |
| |
| *Arguments:* |
| |
| * `projectKey` - The first key to use in the resulting map. |
| * `otherProjectKeys` - Additional keys to use in the resulting map. |
| |
| *Modulation:* |
| |
| * `by()` - Determines how to transform the current object for each key in the resulting map. The number of `by()` |
| modulations should match the number of keys provided. |
| |
| *Considerations:* |
| |
| The `project()` step is similar to `select()` but instead of retrieving historic traverser state, it modulates the |
| current state of the traverser. Each key in the resulting map corresponds to a `by()` modulation in the order they are |
| provided. If a `by()` modulation doesn't produce a value for a particular key (not productive), that key will be omitted |
| from the resulting `Map`. |
| |
| *Exceptions* |
| |
| * If duplicate keys are provided, an `IllegalArgumentException` will be thrown. |
| |
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ProjectStep.java[source], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#project-step[reference] |
| |
| [[repeat-step]] |
| === repeat() |
| |
| *Description:* Iteratively applies a traversal (the "loop body") to all incoming traversers until a stopping |
| condition is met. Optionally, it can emit traversers on each iteration according to an emit predicate. The |
| repeat step supports loop naming and a loop counter via `loops()`. |
| |
| *Syntax:* `repeat(Traversal repeatTraversal)` | `repeat(String loopName, Traversal repeatTraversal)` |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Start Step |Mid Step |Modulated |Domain |Range |
| |N |Y |`emit()`, `until()`, `times()` |`any` |`any` |
| |========================================================= |
| |
| *Arguments:* |
| |
| * `repeatTraversal` - The traversal that represents the loop body to apply on each iteration. |
| * `loopName` - Optional name used to identify the loop for nested loops and to access a specific counter via |
| `loops(loopName)`. |
| |
| *Modulation:* |
| |
| * `emit()` | `emit(Traversal<?, ?> emitTraversal)` | `emit(Predicate<Traverser<?>> emitPredicate)` - Controls if/when a |
| traverser is emitted to the downstream of repeat() in addition to being looped again. If supplied before `repeat(...)` |
| the predicate is evaluated prior to the first iteration (pre-emit). If supplied after `repeat(...)`, the predicate is |
| evaluated after each completed iteration (post-emit). Calling `emit()` without arguments is equivalent to a predicate |
| that always evaluates to true at the given check position. |
| * `until(Traversal<?, ?> untilTraversal)` | `until(Predicate<Traverser<?>> untilPredicate)` - Controls when repetition |
| stops. If supplied before `repeat(...)` the predicate is evaluated prior to the first iteration (pre-check). If the |
| predicate is true, the traverser will pass downstream without any loop iteration. If supplied after `repeat(...)`, the |
| predicate is evaluated after each completed iteration (post-check). When the predicate is true, the traverser stops |
| repeating and passes downstream. |
| * `times(int n)` - Convenience for a loop bound. Equivalent to `until(loops().is(n))` when placed after `repeat(...)` |
| (post-check), and equivalent to `until(loops().is(n))` placed before `repeat(...)` (pre-check) when specified before. |
| See Considerations for details and examples. |
| |
| *Considerations:* |
| |
| - Evaluation order matters. The placement of `emit()` and `until()` relative to `repeat()` controls whether their |
| predicates are evaluated before the first iteration (pre) or after each iteration (post) allowing for `while/do` or |
| `do/while` semantics respectively: |
| - Pre-check / pre-emit: when the modulator appears before `repeat(...)`. |
| - Post-check / post-emit: when the modulator appears after `repeat(...)`. |
| - Global traversal scope: The `repeatTraversal` is a global child. This means all traversers entering the repeat body |
| are processed together as a unified stream with global semantics. `Barrier` (`order()`, `sample()`, etc.) steps within |
| the repeat traversal operate across all traversers collectively rather than in isolation per traverser. |
| - Loop counter semantics: |
| - The loop counter for a given named or unnamed repeat is incremented once per completion of the loop body (i.e., |
| after the body finishes), not before. Therefore, `loops()` reflects the number of completed iterations. |
| - `loops()` without arguments returns the counter for the closest (innermost) `repeat()`. `loops("name")` returns the |
| counter for the named loop. |
| - Re-queuing for the next iteration: |
| - After each iteration, if `until` is not satisfied at the post-check, the traverser is sent back into the loop body |
| for another iteration. If it is satisfied, the traverser exits the loop and proceeds downstream. |
| - Interaction of `times(n)`: |
| - `g.V().repeat(x).times(2)` applies `x` exactly twice; no values are emitted unless `emit()` is specified. |
| - `g.V().emit().repeat(x).times(2)` emits the original input (pre-emit) and then the results of each iteration. |
| - Placing `times(0)` before `repeat(...)` yields no iterations and passes the input downstream unchanged. |
| - Placing `times(0)` after `repeat(...)` yields the same as `times(1)` because of `do/while` semantics. |
| - Errors when `repeatTraversal` is missing: |
| - Using `emit()`, `until()`, or `times()` without an associated `repeat()` will raise an error at iteration time with a |
| message containing: `The repeat()-traversal was not defined`. |
| - Nested repeats and loop names: |
| - Nested `repeat()` steps maintain separate loop counters. Use `repeat("a", ...)` and `loops("a")` to reference a |
| specific counter inside nested loops. |
| |
| *Exceptions* |
| |
| * Using `emit()`, `until()`, or `times()` without a matching `repeat()` will raise an `IllegalStateException` at runtime |
| when the step is initialized during iteration with the message containing: `The repeat()-traversal was not defined`. |
| |
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/RepeatStep.java[source], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#repeat-step[reference], |
| link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/branch/Repeat.feature[tests] |
| |
| [[replace-step]] |
| === replace() |
| |
| *Description:* Returns a string with the specified characters in the original string replaced with the new characters. |
| |
| *Syntax:* `replace(String oldChar, String newChar)` | `replace(Scope scope, String oldChar, String newChar)` |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Start Step |Mid Step |Modulated |Domain |Range |
| |N |Y |N |`String`/`array`/`Iterable` |`String`/`List` |
| |========================================================= |
| |
| *Arguments:* |
| |
| * `oldChar` - The string character(s) in the original string to be replaced. Nullable, a null input will be a no-op and |
| the original string will be returned |
| * `newChar` - The string character(s) to replace with. Nullable, a null input will be a no-op and the original string |
| will be returned |
| * `scope` - Determines the type of traverser it operates on. Both scopes will operate on the level of individual traversers. |
| The `global` scope will operate on individual string traverser. The `local` scope will operate on list traverser with string elements inside. |
| |
| Null values from the incoming traverser are not processed and remain as null when returned. |
| |
| *Exceptions* |
| |
| * For `Scope.global` or parameterless function calls, if the incoming traverser is a non-String value then an `IllegalArgumentException` will be thrown. |
| * For `Scope.local`, if the incoming traverser is not a string or a list of strings then an `IllegalArgumentException` will be thrown. |
| |
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ReplaceGlobalStep.java[source], |
| link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ReplaceLocalStep.java[source (local)], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#replace-step[reference] |
| |
| [[reverse-step]] |
| === reverse() |
| |
| *Description:* Returns the reverse of the incoming traverser |
| |
| *Syntax:* `reverse()` |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Start Step |Mid Step |Modulated |Domain |Range |
| |N |Y |N |`Object` |`Object` |
| |========================================================= |
| |
| *Arguments:* |
| |
| None |
| |
| The behavior of reverse depends on the type of the incoming traverser. If the traverser is a string, then the string is |
| reversed. If the traverser is iterable (Iterable, Iterator, or an array) then a list containing the items in reverse |
| order are returned. All other types (including null) are not processed and are returned unmodified. |
| |
| *Exceptions* |
| |
| * If the incoming traverser is a non-String value then an `IllegalArgumentException` will be thrown. |
| |
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ReverseStep.java[source], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#reverse-step[reference] |
| |
| [[rTrim-step]] |
| === rTrim() |
| |
| *Description:* Returns a string with trailing whitespace removed. |
| |
| *Syntax:* `rTrim()` | `rTrim(Scope scope)` |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Start Step |Mid Step |Modulated |Domain |Range |
| |N |Y |N |`String`/`array`/`Iterable` |`String`/`List` |
| |========================================================= |
| |
| *Arguments:* |
| |
| * `scope` - Determines the type of traverser it operates on. Both scopes will operate on the level of individual traversers. |
| The `global` scope will operate on individual string traverser. The `local` scope will operate on list traverser with string elements inside. |
| |
| Null values from the incoming traverser are not processed and remain as null when returned. |
| |
| *Exceptions* |
| |
| * For `Scope.global` or parameterless function calls, if the incoming traverser is a non-String value then an `IllegalArgumentException` will be thrown. |
| * For `Scope.local`, if the incoming traverser is not a string or a list of strings then an `IllegalArgumentException` will be thrown. |
| |
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/RTrimGlobalStep.java[source], |
| link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/RTrimLocalStep.java[source (local)], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#rTrim-step[reference] |
| |
| [[split-step]] |
| === split() |
| |
| *Description:* Returns a list of strings created by splitting the incoming string traverser around the matches of the given separator. |
| |
| *Syntax:* `split(String separator)` | `split(Scope scope, String separator)` |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Start Step |Mid Step |Modulated |Domain |Range |
| |N |Y |N |`String`/`array`/`Iterable` |`List` |
| |========================================================= |
| |
| *Arguments:* |
| |
| * `separator` - The string character(s) used as delimiter to split the input string. Nullable, a null separator will split on |
| whitespaces. An empty string separator will split on each character. |
| * `scope` - Determines the type of traverser it operates on. Both scopes will operate on the level of individual traversers. |
| The `global` scope will operate on individual string traverser. The `local` scope will operate on list traverser with string elements inside. |
| |
| Null values from the incoming traverser are not processed and remain as null when returned. |
| |
| *Exceptions* |
| |
| * For `Scope.global` or parameterless function calls, if the incoming traverser is a non-String value then an `IllegalArgumentException` will be thrown. |
| * For `Scope.local`, if the incoming traverser is not a string or a list of strings then an `IllegalArgumentException` will be thrown. |
| |
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SplitGlobalStep.java[source], |
| link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SplitLocalStep.java[source (local)], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#split-step[reference] |
| |
| [[subgraph-step]] |
| === subgraph() |
| |
| *Description:* Extracts an edge-induced subgraph from the current graph based on the edges encountered during traversal. |
| |
| *Syntax:* `subgraph(String sideEffectKey)` |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Start Step |Mid Step |Modulated |Domain |Range |
| |N |Y |N |`Edge` |`Edge` |
| |========================================================= |
| |
| *Arguments:* |
| |
| * `sideEffectKey` - The name of the side-effect key that will hold the extracted subgraph. |
| |
| *Modulation:* |
| |
| None |
| |
| *Considerations:* |
| |
| The `subgraph()` step is a side-effect step that extracts edges encountered during traversal and their incident vertices |
| into a new subgraph. The step passes traversers through unchanged while building the subgraph as a side-effect. Subgraph |
| step is a barrier and must fully iterate the traversal before returning any results. |
| |
| *Exceptions* |
| |
| None |
| |
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/SubgraphStep.java[source], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#subgraph-step[reference] |
| |
| [[substring-step]] |
| === substring() |
| |
| *Description:* Returns a substring of the incoming string traverser with a 0-based start index (inclusive) and end index (exclusive). |
| |
| *Syntax:* `substring(int startIndex, int endIndex)` | `substring(Scope scope, int startIndex, int endIndex)` |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Start Step |Mid Step |Modulated |Domain |Range |
| |N |Y |N |`String`/`array`/`Iterable` |`String`/`List` |
| |========================================================= |
| |
| *Arguments:* |
| |
| * `startIndex` - The start index, 0 based. If the start index is negative then it will begin at the specified index counted |
| from the end of the string, or 0 if it exceeds the string length. |
| * `endIndex` - The end index, 0 based. Optional, if it is not specific then all remaining characters will be returned. End |
| index ≤ start index will return the empty string. |
| * `scope` - Determines the type of traverser it operates on. Both scopes will operate on the level of individual traversers. |
| The `global` scope will operate on individual string traverser. The `local` scope will operate on list traverser with string elements inside. |
| |
| Null values from the incoming traverser are not processed and remain as null when returned. |
| |
| *Exceptions* |
| |
| * For `Scope.global` or parameterless function calls, if the incoming traverser is a non-String value then an `IllegalArgumentException` will be thrown. |
| * For `Scope.local`, if the incoming traverser is not a string or a list of strings then an `IllegalArgumentException` will be thrown. |
| |
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SubstringGlobalStep.java[source], |
| link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SubstringLocalStep.java[source (local)], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#substring-step[reference] |
| |
| [[toLower-step]] |
| === toLower() |
| |
| *Description:* Returns the lowercase representation of incoming string traverser, or if `Scope.local` is specified, returns |
| the lowercase representation of each string elements inside incoming list traverser. |
| |
| *Syntax:* `toLower()` | `toLower(Scope scope)` |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Start Step |Mid Step |Modulated |Domain |Range |
| |N |Y |N |`String` |`String`/`List` |
| |========================================================= |
| |
| *Arguments:* |
| |
| * `scope` - Determines the type of traverser it operates on. Both scopes will operate on the level of individual traversers. |
| The `global` scope will operate on individual string traverser. The `local` scope will operate on list traverser with string elements inside. |
| |
| Null values from the incoming traverser are not processed and remain as null when returned. |
| |
| *Exceptions* |
| |
| * For `Scope.global` or parameterless function calls, if the incoming traverser is a non-String value then an `IllegalArgumentException` will be thrown. |
| * For `Scope.local`, if the incoming traverser is not a string or a list of strings then an `IllegalArgumentException` will be thrown. |
| |
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ToLowerGlobalStep.java[source], |
| link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ToLowerLocalStep.java[source (local)], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#toLower-step[reference] |
| |
| [[toUpper-step]] |
| === toUpper() |
| |
| *Description:* Returns the uppercase representation of incoming string traverser, or if `Scope.local` is specified, returns |
| the uppercase representation of each string elements inside incoming list traverser. |
| |
| *Syntax:* `toUpper()` | `toUpper(Scope scope)` |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Start Step |Mid Step |Modulated |Domain |Range |
| |N |Y |N |`String`/`array`/`Iterable` |`String`/`List` |
| |========================================================= |
| |
| *Arguments:* |
| |
| * `scope` - Determines the type of traverser it operates on. Both scopes will operate on the level of individual traversers. |
| The `global` scope will operate on individual string traverser. The `local` scope will operate on list traverser with string elements inside. |
| |
| Null values from the incoming traverser are not processed and remain as null when returned. |
| |
| *Exceptions* |
| |
| * For `Scope.global` or parameterless function calls, if the incoming traverser is a non-String value then an `IllegalArgumentException` will be thrown. |
| * For `Scope.local`, if the incoming traverser is not a string or a list of strings then an `IllegalArgumentException` will be thrown. |
| |
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ToUpperGlobalStep.java[source], |
| link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ToUpperLocalStep.java[source (local)], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#toUpper-step[reference] |
| |
| [[tree-step]] |
| === tree() |
| |
| *Description:* Aggregates the paths of the traversal into a tree data structure. |
| |
| *Syntax:* `tree()` | `tree(String sideEffectKey)` |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Start Step |Mid Step |Modulated |Domain |Range |
| |N |Y |`by()` |`any` |`any` |
| |========================================================= |
| |
| *Arguments:* |
| |
| * `sideEffectKey` - The name of the side-effect key that will hold the aggregated tree. When provided, the step |
| operates as a side-effect step and passes the traverser to the next step unchanged. If omitted, the step acts as a |
| reducing barrier step, and a single traverser containing the aggregated tree is passed to the next step. |
| |
| *Modulation:* |
| |
| * `by()` - Determines how to transform path objects before adding them to the tree. If not specified, the objects |
| themselves are used as tree nodes. If multiple `by()` modulators are provided, they will be applied to each level of the |
| tree according to a round robin. For example, if 2 `by()` modulators are present, the first `by()` will apply to the |
| first, third, fifth... levels of the tree, and the second `by()` will apply to the second, fourth, sixth... levels of |
| the tree. An unlimited number of `by()` modulators may be provided. |
| |
| *Considerations:* |
| |
| The `tree()` step can be used as both a map step and a side-effect step. As a map step, it returns a `Tree` data |
| structure representing the hierarchical paths taken during traversal. As a side-effect step, it stores the tree in a |
| side-effect and passes the traverser to the next step unchanged. The tree structure reflects the branching paths of the |
| traversal, with each level representing a step in the path. |
| |
| *Exceptions* |
| |
| None |
| |
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/TreeStep.java[source], |
| link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/TreeSideEffectStep.java[source (sideEffect)], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#tree-step[reference] |
| |
| [[trim-step]] |
| === trim() |
| |
| *Description:* Returns a string with leading and trailing whitespace removed. |
| |
| *Syntax:* `trim()` | `trim(Scope scope)` |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Start Step |Mid Step |Modulated |Domain |Range |
| |N |Y |N |`String`/`array`/`Iterable` |`String`/`List` |
| |========================================================= |
| |
| *Arguments:* |
| |
| * `scope` - Determines the type of traverser it operates on. Both scopes will operate on the level of individual traversers. |
| The `global` scope will operate on individual string traverser. The `local` scope will operate on list traverser with string elements inside. |
| |
| Null values from the incoming traverser are not processed and remain as null when returned. |
| |
| *Exceptions* |
| |
| * For `Scope.global` or parameterless function calls, if the incoming traverser is a non-String value then an `IllegalArgumentException` will be thrown. |
| * For `Scope.local`, if the incoming traverser is not a string or a list of strings then an `IllegalArgumentException` will be thrown. |
| |
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/TrimGlobalStep.java[source], |
| link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/TrimLocalStep.java[source (local)], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#trim-step[reference] |
| |
| [[valueMap-step]] |
| === valueMap() |
| |
| *Description:* Converts elements to a map representation of their properties. |
| |
| *Syntax:* `valueMap(String... propertyKeys)` | `valueMap(boolean includeTokens, String... propertyKeys)` |
| |
| [width="100%",options="header"] |
| |========================================================= |
| |Start Step |Mid Step |Modulated |Domain |Range |
| |N |Y |`by()`/`with()` |`Element` |`Map` |
| |========================================================= |
| |
| *Arguments:* |
| |
| * `includeTokens` - Determines if the result map should contain entries from `T` (such as `label` and `id`). |
| |
| * `propertyKeys` - If `valueMap()` is provided a list of propertyKeys, then the result map will only contain entries |
| specified by propertyKeys. If the list is empty, then all properties are included. |
| |
| *Modulation:* |
| |
| * `by(Traversal)` - Only a single by() modulator is allowed and it applies to all map values. An attempt to add more |
| than one by() will result in an Exception that contains the message "valueMap()/propertyMap() step can only have one by |
| modulator". |
| * `with(key, value)` - Determines which optional entries to add to the map. The key is "tinkerpop.valueMap.tokens" and |
| the possible values are: |
| ** 0 for no tokens |
| ** 1 for including id (Element) |
| ** 2 for including label (Vertex/Edge) |
| ** 4 for including keys (VertexProperty) |
| ** 8 for including values (VertexProperty) |
| ** 15 for including all |
| |
| See: link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PropertyMapStep.java[source], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#valuemap-step[reference], |
| link:https://tinkerpop.apache.org/docs/x.y.z/reference/#propertymap-step[reference] |