-
Notifications
You must be signed in to change notification settings - Fork 841
Removed AggregateLocalStep, aggregate(Scope, String), and store()
#3233
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -39,7 +39,7 @@ appear by way of some side-effect steps like `aggregate()`: | |
| [gremlin-groovy,modern] | ||
| ---- | ||
| g.V().fold() | ||
| g.V().aggregate(local, 'a').cap('a') | ||
| g.V().local(aggregate('a')).cap('a') | ||
| ---- | ||
| It is worth noting that while a `Path` is not technically a `List` it does present like one and can be manipulated in | ||
|
|
@@ -61,7 +61,7 @@ It may seem simple, but the most obvious choice to modifying what is in a list i | |
| [gremlin-groovy,modern] | ||
| ---- | ||
| g.V().fold().unfold().values('name') | ||
| g.V().aggregate(local,'a').cap('a').unfold().values('name') | ||
| g.V().local(aggregate('a')).cap('a').unfold().values('name') | ||
| ---- | ||
| The above examples show that `unfold()` works quite well when you don't want to preserve the `List` structure of the | ||
|
|
@@ -164,19 +164,19 @@ the use of `aggregate()` to aid in construction of this `List`: | |
| [gremlin-groovy,modern] | ||
| ---- | ||
| g.V().has('name','marko').as('v'). <1> | ||
| aggregate(local,'a'). <2> | ||
| by('age'). | ||
| local(aggregate('a'). <2> | ||
| by('age')). | ||
| repeat(outE().as('e').inV().as('v')). <3> | ||
| until(has('lang','java')). | ||
| aggregate('b'). <4> | ||
| by(select(all,'v').unfold().values('name').fold()). | ||
| aggregate('c'). <5> | ||
| by(select(all,'e').unfold().values('weight').mean()). | ||
| fold(). <6> | ||
| aggregate(local,'a'). <7> | ||
| by(cap('b')). | ||
| aggregate(local,'a'). <8> | ||
| by(cap('c')). | ||
| local(aggregate('a'). <7> | ||
| by(cap('b'))). | ||
| local(aggregate('a'). <8> | ||
| by(cap('c'))). | ||
| cap('a') | ||
| ---- | ||
|
|
@@ -190,9 +190,9 @@ of "java"). Note however that the `by()` modulator overrides that traverser comp | |
| the list of vertices in "v". Those vertices are unfolded to retrieve the name property from each and then are reduced | ||
| with `fold()` back into a list to be stored in the side-effected named "b". | ||
| <5> A similar use of `aggregate()` as the previous step, though this one turns "e" into a stream of edges to calculate | ||
| the `mean()` to store in a `List` called "c". Note that `aggregate()` (short form for `aggregate(global)`) was used | ||
| here instead of `aggregate(local)`, as the former is an eager collection of the elements in the stream | ||
| (`aggregate(local)` is lazy) and will force the traversal to be iterated up to that point before moving forward. | ||
| the `mean()` to store in a `List` called "c". Note that `aggregate()` with `local()` was used | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i think some of this content is in the wrong place. we deprecated in 3.7.x, so we want folks to start using the new form there. if we only deprecate and don't present the new pattern along with it, how will they understand the new form as they face deprecation? i think the 3.7.x docs should reflect the changes in the reference docs, recipes, etc. in that version, UNLESS, we've changed something in the semantics that only allow these changes in 3.8.0 (in which case there really isn't a deprecation path and maybe the #3234 doesn't make sense? thoughts? |
||
| here instead of `aggregate()`, as the latter is an eager collection of the elements in the stream | ||
| (`local(aggregate())` is lazy) and will force the traversal to be iterated up to that point before moving forward. | ||
| Without that eager collection, "v" and "e" would not contain the complete information required for the production of | ||
| "b" and "c". | ||
| <6> Adding `fold()`-step here is a bit of a trick. To see the trick, copy and paste all lines of Gremlin up to but | ||
|
|
@@ -203,11 +203,11 @@ when traversing away from "marko"). The `aggregate()`-steps are side-effects and | |
| through them unchanged. The `fold()` obviously converts those three traversers to a single `List` to make one | ||
| traverser with a `List` inside. That means that the remaining steps following the `fold()` will only be executed one | ||
| time each instead of three, which, as will be shown, is critical to the proper result. | ||
| <7> The single traverser with the `List` of three vertices in it passes to `aggregate(local)`. The `by()` modulator | ||
| <7> The single traverser with the `List` of three vertices in it passes to `local(aggregate())`. The `by()` modulator | ||
| presents an override telling Gremlin to ignore the `List` of three vertices and simply grab the "b" side effect created | ||
| earlier and stick that into "a" as part of the result. The `List` with three vertices passes out unchanged as | ||
| `aggregate(local)` is a side-effect step. | ||
| <8> Again, the single traverser with the `List` of three vertices passes to `aggregate(local)` and again, the `by()` | ||
| `local(aggregate())` is a side-effect step. | ||
| <8> Again, the single traverser with the `List` of three vertices passes to `local(aggregate())` and again, the `by()` | ||
| modulator presents an override to include "c" into the result. | ||
| All of the above code and explanation show that `aggregate()` can be used to construct `List` objects as side-effects | ||
|
|
@@ -236,11 +236,11 @@ g.V(). | |
| bothE().count()). | ||
| fold()) | ||
| g.V(). | ||
| aggregate(local, 'x'). | ||
| local(aggregate('x'). | ||
| by(union(select('x').count(local), <2> | ||
| identity(), | ||
| bothE().count()). | ||
| fold()). | ||
| fold())). | ||
| cap('x') | ||
| ---- | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -454,8 +454,8 @@ image:side-effect-lambda.png[width=175,float=right] | |
| [gremlin-groovy,modern] | ||
| ---- | ||
| g.V().hasLabel('person').sideEffect(System.out.&println) <1> | ||
| g.V().sideEffect(outE().count().aggregate(local,"o")). | ||
| sideEffect(inE().count().aggregate(local,"i")).cap("o","i") <2> | ||
| g.V().sideEffect(outE().count().local(aggregate("o"))). | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: It might be nice to pull all of these docs changes (aside from the semantics docs I suppose) back into the 3.7 deprecation PR. The existing examples in 3.7-dev will still run, however it is preferable to point users towards the preferred |
||
| sideEffect(inE().count().local(aggregate("i"))).cap("o","i") <2> | ||
| ---- | ||
|
|
||
| <1> Whatever enters `sideEffect()` is passed to the next step, but some intervening process can occur. | ||
|
|
@@ -596,26 +596,22 @@ link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gre | |
| image::aggregate-step.png[width=800] | ||
|
|
||
| The `aggregate()`-step (*sideEffect*) is used to aggregate all the objects at a particular point of traversal into a | ||
| `Collection`. The step is uses `Scope` to help determine the aggregating behavior. For `global` scope this means that | ||
| the step will use link:http://en.wikipedia.org/wiki/Eager_evaluation[eager evaluation] in that no objects continue on | ||
| until all previous objects have been fully aggregated. The eager evaluation model is crucial in situations | ||
| where everything at a particular point is required for future computation. By default, when the overload of | ||
| `aggregate()` is called without a `Scope`, the default is `global`. An example is provided below. | ||
| `Collection`. By default, the step will use link:http://en.wikipedia.org/wiki/Eager_evaluation[eager evaluation] in that | ||
| no objects continue on until all previous objects have been fully aggregated. The eager evaluation model is crucial in situations | ||
| where everything at a particular point is required for future computation. | ||
|
|
||
| [gremlin-groovy,modern] | ||
| ---- | ||
| g.V(1).out('created') <1> | ||
| g.V(1).out('created').aggregate('x') <2> | ||
| g.V(1).out('created').aggregate(global, 'x') <3> | ||
| g.V(1).out('created').aggregate('x').in('created') <4> | ||
| g.V(1).out('created').aggregate('x').in('created').out('created') <5> | ||
| g.V(1).out('created').aggregate('x').in('created') <3> | ||
| g.V(1).out('created').aggregate('x').in('created').out('created') <4> | ||
| g.V(1).out('created').aggregate('x').in('created').out('created'). | ||
| where(without('x')).values('name') <6> | ||
| where(without('x')).values('name') <5> | ||
| ---- | ||
|
|
||
| <1> What has marko created? | ||
| <2> Aggregate all his creations. | ||
| <3> Identical to the previous line. | ||
| <3> Who are marko's collaborators? | ||
| <4> What have marko's collaborators created? | ||
| <5> What have marko's collaborators created that he hasn't created? | ||
|
|
@@ -635,31 +631,23 @@ g.V().out('knows').aggregate('x').by('age').cap('x') <1> | |
|
|
||
| <1> The "age" property is not <<by-step,productive>> for all vertices and therefore those values are not included in the aggregation. | ||
|
|
||
| For `local` scope the aggregation will occur in a link:http://en.wikipedia.org/wiki/Lazy_evaluation[lazy] fashion. | ||
|
|
||
| NOTE: Prior to 3.4.3, `local` aggregation (i.e. lazy) evaluation was handled by `store()`-step. | ||
| Aggregation can be controlled to occur in a link:http://en.wikipedia.org/wiki/Lazy_evaluation[lazy] fashion by using | ||
| the step inside `local()`. | ||
|
|
||
| [gremlin-groovy,modern] | ||
| ---- | ||
| g.V().aggregate(global, 'x').limit(1).cap('x') | ||
| g.V().aggregate(local, 'x').limit(1).cap('x') | ||
| g.withoutStrategies(EarlyLimitStrategy).V().aggregate(local,'x').limit(1).cap('x') | ||
| g.V().aggregate('x').limit(1).cap('x') | ||
| g.V().local(aggregate('x')).limit(1).cap('x') | ||
| ---- | ||
|
|
||
| It is important to note that `EarlyLimitStrategy` introduced in 3.3.5 alters the behavior of `aggregate(local)`. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. hmm, that's a nice side-effect of removal. something to call out in Upgrade Docs to help flesh those out more? Just a check but have you confirmed that all these examples do in fact return the same results as the ones with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've manually checked that the examples in the docs run, but I can do a doc build to make sure. |
||
| Without that strategy (which is installed by default), there are two results in the `aggregate()` side-effect even | ||
| though the interval selection is for 1 object. Realize that when the second object is on its way to the `range()` | ||
| filter (i.e. `[0..1]`), it passes through `aggregate()` and thus, stored before filtered. | ||
|
|
||
| [gremlin-groovy,modern] | ||
| ---- | ||
| g.E().aggregate(local,'x').by('weight').cap('x') | ||
| g.E().local(aggregate('x')).by('weight').cap('x') | ||
| ---- | ||
|
|
||
| *Additional References* | ||
|
|
||
| link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#aggregate(java.lang.String)++[`aggregate(String)`], | ||
| link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#aggregate(org.apache.tinkerpop.gremlin.process.traversal.Scope,java.lang.String)++[`aggregate(Scope,String)`] | ||
|
|
||
| [[all-step]] | ||
| === All Step | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think i've asked this elsewhere, but again, have we tested these examples manually to be sure our results are the same just by adding the
localwrapping?