We are proposing a change to the mergeV/E semantics based on initial feedback from its use. We propose making these changes in the upcoming 3.6.2 release.
For clarity in this discussion, we refer to the main argument as “mergeMap” and the onCreate argument as “onCreateMap”. The discussion centers around how to handle the create branch action, we are not concerned with how the match branch is currently handled. mergeV/E(Map mergeMap).option(Merge.onCreate, onCreateMap) The current semantics for merge are to base the create action entirely on the onCreateMap - the mergeMap is ignored. The proposal is to instead base the create action on a union of the mergeMap and the onCreateMap, effectively an inheritance relationship where onCreateMap inherits from mergeMap. Difference in behavior (example): mergeV({T.id: "1", T.label: "person"}).option(onCreate, {"created": true}) This is an intuitive way to ask for a vertex with T.id=“1” and T.label=“person” to be either matched or created. Currently however, this query will create an anonymous vertex with an auto-generated id and the default vertex T.label=“vertex” during the create action, because there is no inheritance from the mergeMap arguments during the create action. We propose to change the semantics such that onCreate inherits the arguments from the mergeMap by default, so that the query as written above creates the vertex {T.id: "1", T.label: "person", "created": true} when run on an empty graph. This has led to numerous user frustrations and even errors in the public documentation: https://tinkerpop.apache.org/docs/current/reference/#mergeedge-step gremlin> g.withSideEffect('map',[(T.label):'Sibling',(from):1,(to):2]). mergeE(select('map')). option(Merge.onCreate,[created:'2022-02-07']). //// (1) option(Merge.onMatch,[updated:'2022-02-07']) //// (2) ==>e[2][1-edge->2] gremlin> g.E().elementMap() ==>[id:2,label:edge,IN:[id:2,label:Dog],OUT:[id:1,label:Dog],created:2022-02-07] Here because T.label='Sibling' was accidentally left out of the onCreateMap and because there is no inheritance from the mergeMap, we created an edge with the wrong label and didn’t even notice. There are other examples in the documentation of this class of user error as well. This is an extremely common error because of the current semantics of the relationship between mergeMap and onCreateMap. Overrides of the element existence criteria (T.id/label and Direction.IN/OUT) in the onCreate map will NOT be allowed, for example, these queries will be prohibited: g.mergeV([T.id: "1", T.label: "foo"]) .option(onCreate, [T.id: "2", T.label: "bar"]) g.mergeE([T.id: "101", T.label: "foo", OUT: "1", IN: "2"]) .option(onCreate, [T.id: "202", T.label: "bar", OUT: "3", IN: "4"]) We will assume a lazy consensus and proceed with these changes if there are no objections by Friday 12/16/22 at 5pm ET.