You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by sp...@apache.org on 2022/01/24 20:46:30 UTC

[tinkerpop] branch TINKERPOP-2681 updated: updated upgrade/io docs and changelog

This is an automated email from the ASF dual-hosted git repository.

spmallette pushed a commit to branch TINKERPOP-2681
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git


The following commit(s) were added to refs/heads/TINKERPOP-2681 by this push:
     new 1cfd694  updated upgrade/io docs and changelog
1cfd694 is described below

commit 1cfd6943dfef9ca9e5d2b7dbb89579a8c8058a48
Author: Stephen Mallette <st...@amazon.com>
AuthorDate: Mon Jan 24 15:44:46 2022 -0500

    updated upgrade/io docs and changelog
---
 CHANGELOG.asciidoc                      |   2 +
 docs/src/dev/io/graphson.asciidoc       | 190 +++++++++++++++++---------------
 docs/src/upgrade/release-3.6.x.asciidoc |  65 +++++++++++
 3 files changed, 167 insertions(+), 90 deletions(-)

diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 191ba91..111110d 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -27,6 +27,8 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
 * Changed TinkerGraph to allow identifiers to be heterogeneous when filtering.
 * Prevented values of `T` to `property()` from being `null`.
 * Added `fail()` step.
+* Added `mergeV()` and `mergeE()` steps.
+* Moved `TraversalOptionParent.Pick` to it's own class as `Pick`.
 * Improved Gherkin test framework to allow for asserting traversal exceptions as a behavior.
 * Fixed query indentation for profile metrics where indent levels were not being respected.
 * `TraversalOpProcessor` no longer accepts a `String` representation of `Bytecode` for the "gremlin" argument which was left to support older versions of the drivers.
diff --git a/docs/src/dev/io/graphson.asciidoc b/docs/src/dev/io/graphson.asciidoc
index 46c5a7d..a20dda5 100644
--- a/docs/src/dev/io/graphson.asciidoc
+++ b/docs/src/dev/io/graphson.asciidoc
@@ -2765,46 +2765,6 @@ The following `Bytecode` example represents the traversal of `g.V().hasLabel('pe
 }
 ----
 
-==== Operator
-
-[source,json]
-----
-{
-  "@type" : "g:Operator",
-  "@value" : "sum"
-}
-----
-
-==== Order
-
-[source,json]
-----
-{
-  "@type" : "g:Order",
-  "@value" : "shuffle"
-}
-----
-
-==== Pick
-
-[source,json]
-----
-{
-  "@type" : "g:Pick",
-  "@value" : "any"
-}
-----
-
-==== Pop
-
-[source,json]
-----
-{
-  "@type" : "g:Pop",
-  "@value" : "all"
-}
-----
-
 ==== Lambda
 
 [source,json]
@@ -2819,6 +2779,16 @@ The following `Bytecode` example represents the traversal of `g.V().hasLabel('pe
 }
 ----
 
+==== Merge
+
+[source,json]
+----
+{
+  "@type" : "g:Merge",
+  "@value" : "onMatch"
+}
+----
+
 ==== Metrics
 
 [source,json]
@@ -2879,6 +2849,26 @@ The following `Bytecode` example represents the traversal of `g.V().hasLabel('pe
 }
 ----
 
+==== Operator
+
+[source,json]
+----
+{
+  "@type" : "g:Operator",
+  "@value" : "sum"
+}
+----
+
+==== Order
+
+[source,json]
+----
+{
+  "@type" : "g:Order",
+  "@value" : "shuffle"
+}
+----
+
 ==== P
 
 [source,json]
@@ -2998,6 +2988,26 @@ The following `Bytecode` example represents the traversal of `g.V().hasLabel('pe
 }
 ----
 
+==== Pick
+
+[source,json]
+----
+{
+  "@type" : "g:Pick",
+  "@value" : "any"
+}
+----
+
+==== Pop
+
+[source,json]
+----
+{
+  "@type" : "g:Pop",
+  "@value" : "all"
+}
+----
+
 ==== Scope
 
 [source,json]
@@ -5149,56 +5159,6 @@ The following `Bytecode` example represents the traversal of `g.V().hasLabel('pe
 }
 ----
 
-==== Operator
-
-[source,json]
-----
-{
-  "@type" : "g:Operator",
-  "@value" : "sum"
-}
-----
-
-==== Order
-
-[source,json]
-----
-{
-  "@type" : "g:Order",
-  "@value" : "shuffle"
-}
-----
-
-==== Pick
-
-[source,json]
-----
-{
-  "@type" : "g:Pick",
-  "@value" : "any"
-}
-----
-
-==== Pop
-
-[source,json]
-----
-{
-  "@type" : "g:Pop",
-  "@value" : "all"
-}
-----
-
-==== Pick
-
-[source,json]
-----
-{
-  "@type" : "g:Pick",
-  "@value" : "any"
-}
-----
-
 ==== Lambda
 
 [source,json]
@@ -5213,6 +5173,16 @@ The following `Bytecode` example represents the traversal of `g.V().hasLabel('pe
 }
 ----
 
+==== Merge
+
+[source,json]
+----
+{
+  "@type" : "g:Merge",
+  "@value" : "onMatch"
+}
+----
+
 ==== Metrics
 
 [source,json]
@@ -5271,6 +5241,26 @@ The following `Bytecode` example represents the traversal of `g.V().hasLabel('pe
 }
 ----
 
+==== Operator
+
+[source,json]
+----
+{
+  "@type" : "g:Operator",
+  "@value" : "sum"
+}
+----
+
+==== Order
+
+[source,json]
+----
+{
+  "@type" : "g:Order",
+  "@value" : "shuffle"
+}
+----
+
 ==== P
 
 `P` expects a single value of a `List` of values. There is special handling for `List` values when it comes to `within`, `without`, `inside`, `outside` and `between`. For `inside`, `outside` and `between`, the expectation is that the collection contain two objects (the rest will be ignored) and those two objects become the arguments to those methods. For `within` and `without`, these methods will accept an arbitrary number of objects in the collection.
@@ -5405,6 +5395,26 @@ Please see <<_p,P>> for additional information on `within`.
 }
 ----
 
+==== Pick
+
+[source,json]
+----
+{
+  "@type" : "g:Pick",
+  "@value" : "any"
+}
+----
+
+==== Pop
+
+[source,json]
+----
+{
+  "@type" : "g:Pop",
+  "@value" : "all"
+}
+----
+
 ==== Scope
 
 [source,json]
diff --git a/docs/src/upgrade/release-3.6.x.asciidoc b/docs/src/upgrade/release-3.6.x.asciidoc
index 6166865..93fac41 100644
--- a/docs/src/upgrade/release-3.6.x.asciidoc
+++ b/docs/src/upgrade/release-3.6.x.asciidoc
@@ -29,6 +29,71 @@ Please see the link:https://github.com/apache/tinkerpop/blob/3.6.0/CHANGELOG.asc
 
 === Upgrading for Users
 
+==== mergeV() and mergeE()
+
+One of the most commonly used patterns in Gremlin is the use of `fold().coalesce(unfold(), ...)` to perform upsert-like
+functionality. While this pattern is quite flexible, it can also be confusing to new users and for certain use cases
+challenging to get the pattern correctly implemented. For providers, the pattern is difficult to properly optimize
+because it can branch into complexity quite quickly making it hard to identify a section of Gremlin for an upsert and
+therefore is not executed as efficiently as it might have been otherwise.
+
+The new `mergeV()` and `mergeE()` steps greatly simplify this pattern and as the pattern is condensed into a single
+step it should be straightforward for providers to optimize as part of their implementations. The following example
+demonstrates just how much easier implementing a basic upsert of a vertex has gotten:
+
+[source,text]
+----
+// prior to 3.6.0, use fold().coalesce(unfold(), ...)
+gremlin> g.V().has('person','name','vadas').has('age', 27).
+......1>   fold().
+......2>   coalesce(unfold().property('age',30),
+......3>            addV('person').property('name','vadas').property('age',27)).
+......4>   elementMap()
+==>[id:2,label:person,name:vadas,age:30]
+
+// 3.6.0
+gremlin> g.mergeV([(T.label): 'person', name:'vadas', age: 27]).
+......1>     option(onMatch, [age: 30]).
+......2>   elementMap()
+==>[id:2,label:person,name:vadas,age:30]
+----
+
+The `fold().coalesce(unfold(), ...)` pattern was even more complicated for upserting edges, but the following example
+demonstrates how much easier `mergeE()` is to follow:
+
+[source,text]
+----
+// prior to 3.6.0, use fold().coalesce(unfold(), ...)
+gremlin> g.V().has('person','name','vadas').as('v').
+......1>            V().has('software','name','ripple').
+......2>            coalesce(__.inE('created').where(outV().as('v')),
+......3>                     addE('created').from('v').property('weight',0.5)).
+......4>   elementMap()
+==>[id:0,label:created,IN:[id:5,label:software],OUT:[id:2,label:person],weight:0.5]
+
+// 3.6.0
+gremlin> ripple = g.V().has('software','name','ripple').next()
+==>v[5]
+gremlin> g.V().has('person','name','vadas').
+......1>   mergeE([(T.label):'created',(IN):ripple, weight: 0.5]).
+......2>   elementMap()
+==>[id:0,label:created,IN:[id:5,label:software],OUT:[id:2,label:person],weight:0.5]
+----
+
+For those currently using the `fold().coalesce(unfold(), ...)` pattern, there is no need to be concerned with
+incompatibility as a result of these new steps. That pattern is still perfectly usable and valid Gremlin, but whenever
+possible it would be best to migrate away from it as graph providers ramp up on 3.6.0 support and introduce important
+write optimizations that will make a big difference in performance.
+
+See: link:https://issues.apache.org/jira/browse/TINKERPOP-2681[TINKERPOP-2681],
+link:https://tinkerpop.apache.org/docs/3.6.0/reference/#mergee-step[mergeE()-step],
+link:https://tinkerpop.apache.org/docs/3.6.0/reference/#mergev-step[mergeV()-step]
+
+==== Moved Pick
+
+`Pick` was formerly a nested class of `TraversalOptionParent`, but has now been promoted to being a class on its own
+in `org.apache.tinkerpop.gremlin.process.traversal.Pick`.
+
 ==== Consistent by() Behavior
 
 The `by()` modulator is critical to the usage of Gremlin. When used in conjunction with a step that supports it, the