[ 
https://issues.apache.org/jira/browse/TINKERPOP-479?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15831607#comment-15831607
 ] 

stephen mallette commented on TINKERPOP-479:
--------------------------------------------

Decided to copy/paste some ideas from [~newkek] from the gremlin-users mailing 
list into this ticket:

{quote}
Using tryNext().orElseGet() will result in multiple roundtrips/transactions to 
the database (with both an embedded graph database like Titan, or with a 
withRemote() interface to a Gremlin Server/other database). The only way to 
avoid that would be to have a `getOrCreate` syntax within the GraphTraversal 
API itself, that the Graph database backend would handle itself when facing 
such syntax. When dealing with a local TinkerGraph tryNext().orElseGet is not a 
problem because it is local, but as soon as you are using a remote database you 
can't currently get around avoiding multiple roundtrips. I had suggested adding 
such an option in the Traversal API which was: 

Would syntaxes for conditional updates/inserts be easier if the steps like 
addV()/addE()/property() were taking an additional boolean argument indicating 
a get-or-create logic in the insertion?

Here's a suggestion:
always create a new Vertex and add the properties (what's happening right now): 
g.addV("mylabel").property("name", "me")

get-or-create is false, always create, same behaviour as above, (what's 
happening right now):
g.addV("mylabel", false).property("name", "me", false)

the true on addV() means "go into getOrCreate mode". Whether a new vertex will 
be created or not is decided by which of the following .property() call has the 
boolean to true or not. When a .property() has true, it will be added to the 
condition of creation. Here, we would go look for a vertex that has the label 
"mylabel" and a property "name" set to "me". If it exists, use it for the rest 
of the traversal, if not, create a new one and add the property "name", "me" to 
it:
g.addV("mylabel", true).property("name", "me", true)

look for a vertex that has the property ("name", "me") and ("surname", "Me"), 
if not found, create a vertex with both these properties:
g.addV("mylabel", true).property("name", "me", true).property("surname", "Me", 
true)

look only for a vertex that has the property ("name", "me"), if not found 
create one, in all cases add the property ("surname", "Me") to it. 
(.property("surname", "Me) is equivalent to .property("surname", "Me", false), 
get-or-create is false -> always create): 
g.addV("mylabel", true).property("name", "me", true).property("surname", "Me")

Applying the same logic to addE() one could add 2 vertices with properties and 
an edge between the two if none, or all exist:
 
g.addV("mylabel", true).property("name", "me", true).property("surname", 
"Me").as("v1") // will always return a vertex, whether it's new or not
 .addV("mylabel", true).property("name", "he", true).property("surname", 
"Me").as("v2") // will always return a vertex, whether it's new or not
 .addE("knows", true).property("since", "born", true).from("v1").to("v2") // 
The Edge will only be added if there wasn't one with the property ("since", 
"born") already existing (would mean that the 2 vertices were already existing 
as well)
{quote}

> Consider Providing "getOrCreate" Functionality
> ----------------------------------------------
>
>                 Key: TINKERPOP-479
>                 URL: https://issues.apache.org/jira/browse/TINKERPOP-479
>             Project: TinkerPop
>          Issue Type: Improvement
>          Components: structure
>    Affects Versions: 3.0.2-incubating
>            Reporter: stephen mallette
>
> One of the most commonly written functions used is good ol' "getOrCreate" 
> where you want to get a {{Vertex}} if it exists or create it with supplied 
> properties if it does not.  We currently have a "helper" function for this on 
> {{ElementHelper}} 
> https://github.com/tinkerpop/tinkerpop3/blob/6d0f00865f673cb0739f6f310e1868425f732924/gremlin-core/src/main/java/com/tinkerpop/gremlin/structure/util/ElementHelper.java#L62
> but perhaps it is time to treat this issue as a first class citizen as part 
> of the Graph API.  I think that some vendors might actually be able to 
> optimize this function as well.  
> Another aspect of "getOrCreate" is "upsert" as well as options to ensure 
> uniqueness.  All of these things we've at some point or another built 
> variations of outside of TinkerPop for applications, data loading, etc.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to