mergeE(): increment counter on match

Hi, is there an easy way to increment an existing edge property based on its current value using mergeE() in one single query? (e.g., counter += 1) Something similar to this:
g.mergeE([(T.label):'called', (from): person1, (to):person2]).
option(Merge.onCreate,['num_calls': 1]).
option(Merge.onMatch,['num_calls': X+1])
g.mergeE([(T.label):'called', (from): person1, (to):person2]).
option(Merge.onCreate,['num_calls': 1]).
option(Merge.onMatch,['num_calls': X+1])
where X is the current value of edge propery num_calls.
Solution:
gremlin> g.mergeE([(Direction.from):44,(Direction.to):8]).valueMap(true)
==>[id:5062,label:route,dist:549]
gremlin> g.mergeE([(Direction.from):44,(Direction.to):8]).valueMap(true)
==>[id:5062,label:route,dist:549]
and then...
R
rpuga44d ago
BTW, I was able to obtain the result I need with a query that looks like this:
p1 = g.addV('person').property('name', 'marko').next()
p2 = g.addV('person').property('name', 'maria').next()
g.V(p1).as("v1").
V(p2).as("v2").
coalesce(
select("v1").outE("called").where(inV().has(id, select("v2").id())),
addE("called").from("v1").to("v2").property("num_calls", 0)).
as("e").
property(
"num_calls",
union(select("e").values("num_calls").unfold(), constant(1)).sum())
p1 = g.addV('person').property('name', 'marko').next()
p2 = g.addV('person').property('name', 'maria').next()
g.V(p1).as("v1").
V(p2).as("v2").
coalesce(
select("v1").outE("called").where(inV().has(id, select("v2").id())),
addE("called").from("v1").to("v2").property("num_calls", 0)).
as("e").
property(
"num_calls",
union(select("e").values("num_calls").unfold(), constant(1)).sum())
but I'm wondering how something similar can be done with mergeE()
VK
Valentyn Kahamlyk42d ago
I think this is impossible now. @spmallette, do you think this is a good use case for passing matching Element as context to onMatch traversal?
F
Flynnt41d ago
And what about delegating this « business stuff » to an event strategy ?
K
kelvinl281641d ago
So long as mergeE is used as a start step, I think you can make this work. But it maybe that this ability needs to get disabled temporarily in order to prevent some error conditions we have seen lately from happening as @Valentyn Kahamlyk mentions while we rework the mergeE semantics a little. I'll post an example in a bit. Need to type one up.
Solution
K
kelvinl281641d ago
gremlin> g.mergeE([(Direction.from):44,(Direction.to):8]).valueMap(true)
==>[id:5062,label:route,dist:549]
gremlin> g.mergeE([(Direction.from):44,(Direction.to):8]).valueMap(true)
==>[id:5062,label:route,dist:549]
and then
gremlin> g.mergeE([(Direction.from):44,(Direction.to):8]).
......1> option(onMatch,property('dist',union(values('dist'), __.constant(1)).sum()).constant([:])).valueMap(true)
==>[id:5062,label:route,dist:550]
gremlin> g.mergeE([(Direction.from):44,(Direction.to):8]).
......1> option(onMatch,property('dist',union(values('dist'), __.constant(1)).sum()).constant([:])).valueMap(true)
==>[id:5062,label:route,dist:550]
K
kelvinl281641d ago
@spmallette has been working on some PRs to improve a few mergeE behaviors. I would like him to comment on whether my example will still be vallid after those updates land. So @rpuga that is one way you can (with the current latest version) make this work. Regarding EventStrategy @Flynnt , those only really make sense when the graph is embedded into the application (as a TinkerGraph can be). In order to catch database wide changes you need something more like the Amazon Neptune CDC stream, or JanusGraph triggers.
F
Flynnt41d ago
Totally agree. And with those, transactional problems can occurs. I think that the best approche for the use case is a change in the data models. And not in using the merge step. with the introduction of a vertex « phone calls » and « call » (for exemple) phone calls beeing liked to the two person and liked to each call. This way a new call is just a new vertex in the graph liked to a relation. And for knowing the count, you can just count the edges.
R
rpuga41d ago
Thanks @Kelvin Lawrence, your solution works great! Adapting it to the example graph I was using, it looks like this:
g.mergeE([(T.label):'called', (from):p1, (to):p2]).
option(Merge.onCreate, ['num_calls': 1]).
option(Merge.onMatch, property('num_calls', union(values('num_calls'), constant(1)).sum()).constant([:]))
g.mergeE([(T.label):'called', (from):p1, (to):p2]).
option(Merge.onCreate, ['num_calls': 1]).
option(Merge.onMatch, property('num_calls', union(values('num_calls'), constant(1)).sum()).constant([:]))
K
kelvinl281640d ago
FYI @spmallette and @Valentyn Kahamlyk this is I think one of the key cases where being able to do additional work inside onMatch is very useful.
VK
Valentyn Kahamlyk40d ago
Will we have same behavior for starting and mid-traversal mergeE?
K
kelvinl281640d ago
Currently no unfortunately. It will depend on what is in the stream until changes can be made to the way the step is working today. I called out this case mainly as an example of a behavior that needs to be supported in some way (as it is very useful).
Want results from more Discord servers?
Add your server
More Posts
Serialization IssueI have a weird error, when I am connecting with JanusGraph gremlin client using `conf/remote-graph-Design decision related to multiple heterogenous relational graphsI'm working with over 100k instances of heterogeneous, relational node-and-edge attributed graphs, eStackoverflow when adding a larger list of property values using traverser.property()Hey, we encounter a stack overflow: ``` Exception during Transaction, rolling back ... org.apache.tijava: package org.apache.tinkerpop.shaded.jackson.core does not existWhile trying to `mvn clean install` with jdk11, I ran into the above error using the master branch. Performance issue in large graphsWhen performing changes in large graph (ca. 100K nodes, 500K edges) which is stored in one kryo fileConcurrent queries to authentication required sever resulted in 401 errorHey guys, playing around with gremlin & encountered this very odd error where concurrent queries wilDiscrepancy between console server id conventions and NeptuneSo I'm working with my test server and on Neptune--and I'm noticing a difference in the type of the how to connect the amothic/neptune container to the volume?I need to know which directory needs to attach to containeer. so that the data is stored safely. eveDocker yaml authentication settings (gremlinserver.authentication) questionDoes anyone have any experience setting up authentication on Docker by using the supplied .yaml fileGremlin Injection Attacks?Is anyone talking about or looking into attacks and mitigations for Gremlin Injection Attacks? That Returned vertex properties (JS client)Hi, I've got a question regarding the returned vertex value when using the JS client. How come non-aAnyone using Tinkerpop docker as a local Cosmos replacementRunning into some random issues. Looking for tips and tricks.Configuring Websockets connection to pass through a proxy serverHey, I'm working on making G.V() fully proxy aware, but I can't seem to get websockets connection tpython goblin vs spring-data-goblin for interactions with gremlin serverI want an OGM to interact with my gremlin server. What would be a good choice?Is there any open source version of data visualizer for aws neptune?Is there any open source version of data visualizer for aws neptune. I'll need it since it essentialDynamic select within query not working.Any insights or help would be greatly appreciated. I have to pass a list of lists in the format beAdding multiple properties to a vertex using gremlin-goHello Community, I have a question regarding how multiple properties can be added to a vertex using Is it possible to walk 2 different graphs using custom TraversalStrategy in Gremlin?I have 2 different graphs in 2 different Neptune cluster. Both of them can have few reference verticSideEffect a variable, Use it later after BarrierStep?I seek a query that builds a list and then needs to both sum the list's mapped values and divide theMemory issue on repeatI am traversing all nodes occuring in the same cluster given one of the nodes in that cluster. Surp