Steps O-T
option
Feature: (Modifier) Specifies the conditions for a branch query.
Note: This step must be used with
branch().
optional
Feature: (Branch) Returns the traversal result if the sub-traversal produces a result. Otherwise, it returns the input object.
// Returns the "knows" relationships or the information of people who have no friends.
g("thinkerpop").V("1;2;4;6").hasLabel("person").optional(outE("knows"))
==> {"label":"knows","pk":"1","sk":"4","weight":1.0}
==> {"label":"knows","pk":"1","sk":"2","weight":0.5}
==> {"label":"person","age":32,"name":"josh","pk":"4"}
==> {"label":"person","age":27,"name":"vadas","pk":"2"}
==> {"label":"person","age":35,"name":"peter","pk":"6"}or
Feature: (Filter) Returns the input if at least one sub-traversal produces a result.
// Finds people who are 27 years old or have at least two friends.
g("thinkerpop").V("1;2;4;6").hasLabel("person").or(outE("knows").count().is(P.gte(2)),filter("age=27"))
==> {"label":"person","age":29,"name":"marko","pk":"1"}
==> {"label":"person","age":27,"name":"vadas","pk":"2"}order
Feature: (Map) Sorts the results.
Note:
You can use the
by()modifier to specify the sorting criteria and order: ascending (incr), descending (decr), or random (shuffle).By default, results are sorted by their values. You can specify a field value or a sub-traversal as the sorting rule.
The default order is ascending.
You can use multiple
by()steps to specify multiple sorting rules.
This step implicitly inserts a
barrier().
// Sorts by pk in ascending order. If pks are the same, sorts by sk in descending order.
g("thinkerpop").E("1;2;3;4;5;6").hasLabel("created").order().by("pk").by("sk",Order.decr)
==> {"label":"created","pk":"1","sk":"3","weight":0.4}
==> {"label":"created","pk":"4","sk":"5","weight":1.0}
==> {"label":"created","pk":"4","sk":"3","weight":0.4}
==> {"label":"created","pk":"6","sk":"3","weight":0.2}
// Sorts by the number of "knows" relationships in descending order.
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").order().by(outE("knows").count(),Order.decr)
==> {"label":"person","age":29,"name":"marko","pk":"1"}
==> {"label":"person","age":32,"name":"josh","pk":"4"}
==> {"label":"person","age":27,"name":"vadas","pk":"2"}
==> {"label":"person","age":35,"name":"peter","pk":"6"}
// Randomly sorts the ages.
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").values("age").order().by(Order.shuffle)
==> 32
==> 35
==> 29
==> 27out
Feature: (Entity) Traverses from a vertex to an adjacent vertex.
Note:
This step only supports graph access mode.
You can use a parameter to specify the label of the edge to traverse.
If you do not specify a parameter, all adjacent edges are traversed by default.
This step is broken down into
outE().limit(50).inV(). This means a limit of 50 is applied to the outgoing edges. If this is insufficient for your requirements, use theoutE().limit(300).inV()pattern.For system protection, the number of outgoing edges cannot exceed 50,000.
out().out()is optimized and broken down intooutE().limit(50).outE().limit(50).inV().This saves one vertex access.
The
skeyvalue of the edge from the firstoutE()is thepkeyvalue for the edge in the secondoutE().This optimization does not take effect if
path()exists in the subsequent traversal.
g("thinkerpop").V("1").hasLabel("person").out("knows")
==> {"label":"person","age":32,"name":"josh","pk":"4"}
==> {"label":"person","age":27,"name":"vadas","pk":"2"}
g("thinkerpop").V("1").hasLabel("person").out()
==> {"label":"software","lang":"java","name":"lop","pk":"3"}
==> {"label":"person","age":32,"name":"josh","pk":"4"}
==> {"label":"person","age":27,"name":"vadas","pk":"2"}outE
Feature: (Entity) Traverses from a vertex to an adjacent edge.
Note:
Graph access mode: You can use a parameter to specify the label of the edge to traverse.
If you do not specify a parameter, all adjacent edges are traversed by default.
// By default, the pkey of the input vertex is used as the traversal field.
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").outE("knows")
==> {"label":"knows","pk":"1","sk":"4","weight":1.0}
==> {"label":"knows","pk":"1","sk":"2","weight":0.5}
g("thinkerpop").V("1").hasLabel("person").outE("knows","created")
==> {"label":"created","pk":"1","sk":"3","weight":0.4}
==> {"label":"knows","pk":"1","sk":"4","weight":1.0}
==> {"label":"knows","pk":"1","sk":"2","weight":0.5}P
Feature: (Function) Describes comparison logic.
Format
Type | Name | Description | Example |
Basic | P.eq | Equal to | P.eq(25) |
P.neq | Not equal to | P.neq(25) | |
P.gt | Greater than | P.gt(25) | |
P.gte | Greater than or equal to | P.gte(25) | |
P.lt | Less than | P.lt(25) | |
P.lte | Less than or equal to | P.lte(25) | |
P.inside | Within the range: (a, b) | P.inside(25, 32) | |
P.outside | Outside the range: (-inf, a) U (b, inf) | P.outside(25, 32) | |
P.between | Between: [a, b) | P.between(25, 32) | |
P.within | Within the set | P.within(25, 32, 33, 35) | |
P.without | Not within the set | P.without(25, 32, 33, 35) | |
Combined | and | And | P.gt(25) and P.lt(30) |
or | Or | P.eq(25) or P.eq(30) | |
negate | Reverse | P.eq(25).negate() |
Note
Only number and string types are supported.
Applies to filter steps such as
is()andhas().Differences between
Pand expressionsP: Applies to scenarios with one parameter. The parameter does not need a name.Expression: Applies to scenarios with multiple parameters. The parameters must have names.
Their features partially overlap. Use the one that best suits your scenario.
// Finds people who are 27 years old or have at least two friends.
g("thinkerpop").V("1;2;4;6").hasLabel("person").or(outE("knows").count().is(P.gte(2)),values("age").is(P.eq(27)))
==> {"label":"person","age":29,"name":"marko","pk":"1"}
==> {"label":"person","age":27,"name":"vadas","pk":"2"}
// This is equivalent to:
// The first sub-traversal of or() has no name, so you can only use P. The second parameter is age, so you can use an expression with filter instead.
g("thinkerpop").V("1;2;4;6").hasLabel("person").or(outE("knows").count().is(P.gte(2)),filter("age=27"))path
Feature (Map): Returns the traversal path.
Note
path()only shows the result of each step. To include edge information in the path when usingout(), you must explicitly useoutE().inV().You can use the
by()modifier to specify the fields to record in the path.You can use the
PathRecordStrategypolicy to customize the type of information that this step records in the path.
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").out().out().values("name").path()
==> {"value":[{"label":"person","age":29,"name":"marko","pk":"1"},{"label":"person","age":32,"name":"josh","pk":"4"},{"label":"software","lang":"java","name":"lop","pk":"3"},"lop"],"labels":[[],[],[],[]]}
==> {"value":[{"label":"person","age":29,"name":"marko","pk":"1"},{"label":"person","age":32,"name":"josh","pk":"4"},{"label":"software","lang":"java","name":"ripple","pk":"5"},"ripple"],"labels":[[],[],[],[]]}
// Explicitly call outE().inV() to show edge information.
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").outE().inV().outE().inV().values("name").path()
==> {"value":[{"label":"person","age":29,"name":"marko","pk":"1"},{"label":"knows","pk":"1","sk":"4","weight":1.0},{"label":"person","age":32,"name":"josh","pk":"4"},{"label":"created","pk":"4","sk":"3","weight":0.4},{"label":"software","lang":"java","name":"lop","pk":"3"},"lop"],"labels":[[],[],[],[],[],[]]}
==> {"value":[{"label":"person","age":29,"name":"marko","pk":"1"},{"label":"knows","pk":"1","sk":"4","weight":1.0},{"label":"person","age":32,"name":"josh","pk":"4"},{"label":"created","pk":"4","sk":"5","weight":1.0},{"label":"software","lang":"java","name":"ripple","pk":"5"},"ripple"],"labels":[[],[],[],[],[],[]]}
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").out().out().path().by("name")
==> {"value":["marko","josh","lop"],"labels":[[],[],[]]}
==> {"value":["marko","josh","ripple"],"labels":[[],[],[]]}PathRecordStrategy
Feature: (Policy) Customizes the type of information that
path()records.Format: Classifies information into the following three types:
This policy is an extension developed by IGraph.
PathRecord.vertex: VertexPathRecord.edge: EdgePathRecord.map: Map type
Note:
By default, all types of information are recorded.
This policy must be used with
withStrategies().This policy helps reduce the amount of data transferred.
// By default, all types of information are recorded.
g("thinkerpop").V("4").hasLabel("person").outE().inV().path()
==> {"value":[{"label":"person","age":32,"name":"josh","pk":"4"},{"label":"created","pk":"4","sk":"3","weight":0.4},{"label":"software","lang":"java","name":"lop","pk":"3"}],"labels":[[],[],[]]}
==> {"value":[{"label":"person","age":32,"name":"josh","pk":"4"},{"label":"created","pk":"4","sk":"5","weight":1.0},{"label":"software","lang":"java","name":"ripple","pk":"5"}],"labels":[[],[],[]]}
// Records only vertex information.
g("thinkerpop").V("4").withStrategies(PathRecordStrategy(PathRecord.vertex)).hasLabel("person").outE().inV().path()
==> {"value":[{"label":"person","age":32,"name":"josh","pk":"4"},{"label":"software","lang":"java","name":"lop","pk":"3"}],"labels":[[],[]]},
==> {"value":[{"label":"person","age":32,"name":"josh","pk":"4"},{"label":"software","lang":"java","name":"ripple","pk":"5"}],"labels":[[],[]]}
// Records only edge information.
g("thinkerpop").V("4").withStrategies(PathRecordStrategy(PathRecord.edge)).hasLabel("person").outE().inV().path()
==> {"value":[{"label":"created","pk":"4","sk":"3","weight":0.4}],"labels":[[]]}
==> {"value":[{"label":"created","pk":"4","sk":"5","weight":1.0}],"labels":[[]]}project
Feature: (Map) Maps input objects to a map<string, object>.
Note: You can use the
by()modifier to specify the value for the mapping.
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").project("a","b").by(outE("knows").count()).by("age").order().by(select("b"))
==> {"\"a\"":0,"\"b\"":27}
==> {"\"a\"":2,"\"b\"":29}
==> {"\"a\"":0,"\"b\"":32}
==> {"\"a\"":0,"\"b\"":35}
// The number of items created and the number of friends known by each person.
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").project("created","knows").by(outE("created").count()).by(outE("knows").count())
==> {"\"created\"":1,"\"knows\"":2}
==> {"\"created\"":2,"\"knows\"":0}
==> {"\"created\"":0,"\"knows\"":0}
==> {"\"created\"":1,"\"knows\"":0}properties
Feature: (Map) Returns field names and field values.
Note:
You can specify which properties to return. By default, all properties are returned.
values()returns field values.
g("thinkerpop").V("1;2").hasLabel("person").properties()
==> {"age":29}
==> {"name":"marko"}
==> {"pk":"1"}
==> {"age":27}
==> {"name":"vadas"}
==> {"pk":"2"}
g("thinkerpop").V("1;2").hasLabel("person").properties("name","age")
==> {"age":29}
==> {"name":"marko"}
==> {"age":27}
==> {"name":"vadas"}propertyMap
Feature: (Map) Returns a map of field names and field values.
Note: You can specify which properties to return. By default, all properties are returned.
g("thinkerpop").V("1;2").hasLabel("person").propertyMap()
==> {"\"age\"":{"age":29},"\"name\"":{"name":"marko"},"\"pk\"":{"pk":"1"}}
==> {"\"age\"":{"age":27},"\"name\"":{"name":"vadas"},"\"pk\"":{"pk":"2"}}
g("thinkerpop").V("1;2").hasLabel("person").propertyMap("name","age")
==> {"\"age\"":{"age":29},"\"name\"":{"name":"marko"}}
==> {"\"age\"":{"age":27},"\"name\"":{"name":"vadas"}}PushDownStrategy
Feature: (Policy) Pushes down side effect retrieval to the storage layer for execution.
Note: In compute-intensive scenarios, pushing down side effect retrieval to the storage layer reduces data transfer.
This policy is an IGraph extension.
// The maximum product of each person's age and the ages of others.
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").aggregate("x").by("age").V("1;2;3;4;5;6").hasLabel("person").values("age").as("y").local(select("x").unfold().math("_ * y").max())
==> 1015
==> 1120
==> 945
==> 1225
// Pushes down the logic for calculating the maximum value to be executed immediately after getting y. This reduces the duration for which y needs to be stored.
g("thinkerpop").withStrategies(PushDownStrategy("x")).V("1;2;3;4;5;6").hasLabel("person").aggregate("x").by("age").V("1;2;3;4;5;6").hasLabel("person").values("age").as("y").local(select("x").unfold().math("_ * y").max())
==> 1015
==> 1120
==> 945
==> 1225range
Function: Truncates the results.
Format:
range(low,high).lowis of the uint32 type, andhighis of the int64 type. We recommend thathighbe less than 50,000.Note: If high is -1, all results from
lowonward are returned. Otherwise,highmust be greater thanlow.
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").order().by("pk").range(1,2)
==> {"label":"person","age":27,"name":"vadas","pk":"2"}
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").order().by("pk").range(1,-1)
==> {"label":"person","age":27,"name":"vadas","pk":"2"}
==> {"label":"person","age":32,"name":"josh","pk":"4"}
==> {"label":"person","age":35,"name":"peter","pk":"6"}
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").order().by("pk").range(1,0)
==> {"ErrorCode":20040,"ErrorDescription":"gremlin 'range(global)' step invalid (low(1) > high(0) in 'range')"}repeat
Feature: (Branch) Loops through a traversal.
Note:
You can use this step with other steps, such as
times()anduntil(), to specify the loop termination condition.You can use this step with
emit()to record the intermediate results of the loop.For system protection, do not run inefficient queries. For example, do not run an unlimited loop on a graph that contains cycles.
For system protection, specify a
limit()for each traversal within the loop. Each degree is limited to 50,000 results.
# Traverses out twice and gets the traversal path.
g("thinkerpop").V("1").hasLabel("person").repeat(out()).times(2).path().by("name")
==> {"value":["marko","josh","lop"],"labels":[[],[],[]]}
==> {"value":["marko","josh","ripple"],"labels":[[],[],[]]}
# Do not run until() on a graph with cycles.
# Starts from the specified node and performs a breadth-first search until the "ripple" node is found.
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").until(has("name","ripple")).repeat(out()).path().by("name")
==> {"value":["marko","josh","ripple"],"labels":[[],[],[]]}
==> {"value":["josh","ripple"],"labels":[[],[]]}
# emit() - Traverses two degrees and outputs the intermediate paths.
g("thinkerpop").V("1").hasLabel("person").repeat(out()).times(2).emit().path().by("name")
==> {"value":["marko","lop"],"labels":[[],[]]}
==> {"value":["marko","josh"],"labels":[[],[]]}
==> {"value":["marko","vadas"],"labels":[[],[]]}
==> {"value":["marko","josh","lop"],"labels":[[],[],[]]}
==> {"value":["marko","josh","ripple"],"labels":[[],[],[]]}
# emit() - Traverses two degrees and outputs the intermediate paths. This includes the path before the repeat starts.
g("thinkerpop").V("1").hasLabel("person").emit().repeat(out()).times(2).path().by("name")
==>[marko]
==> {"value":["marko"],"labels":[[]]}
==> {"value":["marko","lop"],"labels":[[],[]]}
==> {"value":["marko","josh"],"labels":[[],[]]}
==> {"value":["marko","josh","lop"],"labels":[[],[],[]]}
==> {"value":["marko","josh","ripple"],"labels":[[],[],[]]}
==> {"value":["marko","vadas"],"labels":[[],[]]}sack
Feature: (Map) Returns the sack value of an entity.
Note: For more information about the initialization value, split rule, and merge rule for sack values, see
withSack().
sample
Feature: (Filter) Samples the results.
Format:
sample([Sample.upsampling,][Sample.duplicatable,]NUM)[by(field)].NUMis of the uint32 type.Sample.duplicatablespecifies that duplicates are not removed. This allows the number of output objects to exceed the number of input objects. For example, for the input `a a b c`, sampling 3 with deduplication returns at most two `a`s. Without deduplication, it might return three `a`s.Sample.upsamplingenables upsampling. If the total number of input objects is less than the specified sample size, upsampling ensures that the specified number of results is returned, unless the input is empty. When upsampling is active, the `duplicatable` setting is ignored.By default, results are deduplicated and not upsampled.
Note:
Random sampling is used by default.
You can use the
by()modifier to use a field's value as the sampling weight. A higher weight increases the probability of being sampled.
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").outE("created").sample(Sample.upsampling,Sample.duplicatable,5).by("weight")
==> {"label":"created","pk":"1","sk":"3","weight":0.4}
==> {"label":"created","pk":"4","sk":"5","weight":1.0}
==> {"label":"created","pk":"4","sk":"5","weight":1.0}
==> {"label":"created","pk":"4","sk":"5","weight":1.0}
==> {"label":"created","pk":"6","sk":"3","weight":0.2}select
Feature: (Map) Returns the value of a label that was marked by
as().Note:
When this step retrieves multiple label values, it returns a
map<label, objects>.You can use the
by()modifier to specify a field of the label to retrieve.This step can be used with
Pop.first,Pop.last, andPop.all. These select the first, last, or all occurrences of a label in the path, respectively.
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").as("x").select("x")
==> {"label":"person","age":29,"name":"marko","pk":"1"}
==> {"label":"person","age":32,"name":"josh","pk":"4"}
==> {"label":"person","age":27,"name":"vadas","pk":"2"}
==> {"label":"person","age":35,"name":"peter","pk":"6"}
// The filter step takes the labeled objects as input.
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").as("x").filter("age>=32").select("x")
==> {"label":"person","age":32,"name":"josh","pk":"4"}
==> {"label":"person","age":35,"name":"peter","pk":"6"}
// A step can be associated with multiple labels using as().
// When select() gets multiple label values, it returns a map<label,objects>.
// select() is modified by by() to specify which field of the label to get.
g("thinkerpop").V("1;2").hasLabel("person").as("x","y","z").select("x","y","z").by("pk").by("name").by("age")
==> {"\"x\"":"1","\"y\"":"marko","\"z\"":29}
==> {"\"x\"":"2","\"y\"":"vadas","\"z\"":27}
// The value of the first occurrence of the label "a".
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").as("a").repeat(out().as("a")).times(2).select(Pop.first,"a")
==> {"label":"person","age":29,"name":"marko","pk":"1"}
==> {"label":"person","age":29,"name":"marko","pk":"1"}
// The value of the last occurrence of the label "a".
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").as("a").repeat(out().as("a")).times(2).select(Pop.last,"a")
==> {"label":"software","lang":"java","name":"lop","pk":"3"}
==> {"label":"software","lang":"java","name":"ripple","pk":"5"}
// All occurrences of the label "a". This is equivalent to select("a").
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").as("a").repeat(out().as("a")).times(2).select(Pop.all,"a")
==> [{"label":"person","age":29,"name":"marko","pk":"1"},{"label":"person","age":32,"name":"josh","pk":"4"},{"label":"software","lang":"java","name":"lop","pk":"3"}]
==> [{"label":"person","age":29,"name":"marko","pk":"1"},{"label":"person","age":32,"name":"josh","pk":"4"},{"label":"software","lang":"java","name":"ripple","pk":"5"}]simplePath
Feature: (Filter) Returns paths without cycles.
Note:
You can use the
by()modifier to specify the fields to use for cycle detection.cyclePath()returns paths with cycles.
g("thinkerpop").V("1").hasLabel("person").out().out().simplePath().path()
==> {"value":[{"label":"person","age":29,"name":"marko","pk":"1"},{"label":"person","age":32,"name":"josh","pk":"4"},{"label":"software","lang":"java","name":"lop","pk":"3"}],"labels":[[],[],[]]}
==> {"value":[{"label":"person","age":29,"name":"marko","pk":"1"},{"label":"person","age":32,"name":"josh","pk":"4"},{"label":"software","lang":"java","name":"ripple","pk":"5"}
g("thinkerpop").V("1").hasLabel("person").out().out().simplePath().path().by("name")
==> {"value":["marko","josh","lop"],"labels":[[],[],[]]}
==>{"value":["marko","josh","ripple"],"labels":[[],[],[]]}store
Feature: (sideEffect) During a traversal, aggregates input objects into a list<object> and saves it in a sideEffect.
Note:
This step does not affect the input objects. The original objects are passed to the next step.
The list<object> generated by this step is read-only. You can retrieve its value at any point in the subsequent traversal using
cap().Note: Retrieving the value with select() is not recommended. This is because
select()returns alist<object>for each entity, which results in multiple identical lists if there are multiple entities.
You can use the
by()modifier to specify the field value for aggregation.You can use
aggregate()to perform blocking aggregation.
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").store("x").by("name")
==> {"label":"person","age":29,"name":"marko","pk":"1"}
==> {"label":"person","age":32,"name":"josh","pk":"4"}
==> {"label":"person","age":27,"name":"vadas","pk":"2"}
==> {"label":"person","age":35,"name":"peter","pk":"6"}
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").store("x").by("name").cap("x")
==> ["josh","marko","peter","vadas"]
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").store("x").by("name").filter("age>=32").cap("x")
==> ["josh","marko","peter","vadas"]
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").store("x").by("name").outE("knows").store("y").cap("x","y").dedup()
==> {"\"x\"":["josh","marko","peter","vadas"],"\"y\"":[{"label":"knows","pk":"1","sk":"2","weight":0.5},{"label":"knows","pk":"1","sk":"4","weight":1.0}]}sum
Feature: (Map) Calculates the sum of the input objects.
Note:
This step only supports number-type inputs and does not support the
booltype.sum(Scope.local)supports iterator-type inputs. The elements in the iterator must be numbers and cannot be of thebooltype.This step implicitly inserts a
barrier().
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").values("age").sum()
==> 123
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").values("age").fold().sum(Scope.local)
==> 123
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").aggregate("x").by("age").cap("x").sum(Scope.local)
==> 123T
Feature: (Function) Extracts information from input elements.
Format
T.id: Returns the pkey field value of the entity.
T.label: Returns the label of the entity (the corresponding label in the graph).
T.key: Returns the field name of the element.
T.value: Returns the field value of the element.
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").has(T.id,P.eq("1"))
==> {"label":"person","age":29,"name":"marko","pk":"1"}
// After two traversals, there are no more "person" entities, only "software" entities.
g("thinkerpop").V("1").hasLabel("person").out().out().has(T.label,P.eq("person"))
==> Empty result
// Sorts by field name.
g("thinkerpop").V("1").hasLabel("person").properties().order().by(T.key)
==> {"age":29}
==> {"name":"marko"}
==> {"pk":"1"}
// Sorts by field value.
g("thinkerpop").V("1").hasLabel("person").properties().order().by(T.value)
==> {"age":29}
==> {"pk":"1"}
==> {"name":"marko"}tail
Feature: (Filter) Truncates the results. Keeps the last
NUMresults.Format:
tail(NUM).NUMis of the uint32 type. We recommend thatNUMis less than 50,000.Note
limit()keeps the firstNUMresults.This step implicitly inserts a
barrier().
g("thinkerpop").V("1;2;3;4;5;6").hasLabel("person").tail(2)
==> {"label":"person","age":27,"name":"vadas","pk":"2"}
==> {"label":"person","age":35,"name":"peter","pk":"6"}times
Feature: (Modifier) Specifies the number of times to loop a traversal.
Note: This step must be used with
repeat().