gremlin-http multiple queries with Sack only updates the last vertex in the payload

142 views
Skip to first unread message

Mitesh Patel

unread,
Jul 21, 2017, 8:04:29 AM7/21/17
to Gremlin-users
Hi,
I am facing a weird situation with sack only being applied to last query when firing multiple queries with gremlin-http.
A User (vertex) -> Buys (edge) -> Item (vertex)

I need to create an edge if the user is buying this item for the first time and at the same time increment the property at Item vertex with unique_user_bought_count. I am using sack with Choose to figure out if the property exists then increment by 1 else create this property with a value of 1.
Lets say User ABC bought two items Item1 and Item2. I need to create an edge between ABC and Item1, Item2 if it does not exist and create/modify the unique_user_bought_count at Item1, Item2

This is my query. For ease of readability, I have broken down these queries in multiple lines. My payload to gremlin-http includes all these queries in one request.
// Check if user exists else create a vertex
user = g.V().has('userid', 'ABC').tryNext().orElseGet{graph.addVertex('userid', 'ABC')};
// Check if item exists else create a vertex
item1 = g.V().has('itemid', 'Item1').tryNext().orElseGet{graph.addVertex('itemid', 'Item1')}
// Check if edge exists else create the edge. Check if unique_user_bought_count property exists at Item Vertex to increment else create with value 1
edge1 = g.V().has('userid', 'ABC').out('bought', g.V().has('itemid', 'Item1').tryNext().orElseGet{
                          user.addEdge(item1); 
                          g.withSack(0).V().has('itemid', 'Item1').choose(has('unique_user_bought_count'), 
                                          sack(assign).by('unique_user_bought_count').sack(sum).by(constant(1)).property('unique_user_bought_count',sack()),property('unique_user_bought_count',1))
              };
// Create another item if it does not exist
item2 = g.V().has('itemid', 'Item2').tryNext().orElseGet{graph.addVertex('itemid', 'Item2')}
// Check if edge exists else create the edge. Check if unique_user_bought_count property exists at Item Vertex to increment else create with value 1
edge1 = g.V().has('userid', 'ABC').out('bought', g.V().has('itemid', 'Item2').tryNext().orElseGet{
                          user.addEdge(item2); 
                          g.withSack(0).V().has('itemid', 'Item2').choose(has('unique_user_bought_count'), 
                                          sack(assign).by('unique_user_bought_count').sack(sum).by(constant(1)).property('unique_user_bought_count',sack()),property('unique_user_bought_count',1))
              };

Problem - Edge from user -> item gets created correctly but the property gets updated only for the last item. Is there anything that I am doing wrong. I am assuming that we do not need to clone sack since this is primitive. But I did try with clone as well, but to no avail.

Can someone help me with this problem or point me where am I going wrong with the query?

Thanks in advance,
Mitesh

Mitesh Patel

unread,
Jul 24, 2017, 6:28:10 AM7/24/17
to Gremlin-users
I would really appreciate some help from experts here. Thanks in advance.

Marko Rodriguez

unread,
Jul 24, 2017, 9:58:33 AM7/24/17
to gremli...@googlegroups.com
Hello,

You code and data model are very involved. Can you please reformulate your question using TinkerFactory.createModern() so its easier for us to pinpoint the exact problem you are having.

Thank you,
Marko.
--
You received this message because you are subscribed to the Google Groups "Gremlin-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to gremlin-user...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/gremlin-users/31f42721-f14e-4d6f-9519-c2e0ccbff1a2%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Daniel Kuppitz

unread,
Jul 24, 2017, 12:00:44 PM7/24/17
to gremli...@googlegroups.com
Hi Mitesh,

the following snippet should do what you need:

graph = TinkerGraph.open()
g = graph.traversal()

user = g.V().has("userid", "ABC").tryNext().orElseGet {
  graph.addVertex("userid", "ABC")
}

g.V(user).as("u").
  coalesce(V().has("itemid", "Item1"), addV().property("itemid", "Item1")).as("i1").
  coalesce(
    inE("bought").where(outV().as("u")).inV().sack(assign).by("unique_user_bought_count").sack(sum).by(constant(1)).property("unique_user_bought_count", sack()),
    addE("bought").from("u").to("i1").inV().property("unique_user_bought_count", 1)).
  coalesce(V().has("itemid", "Item2"), addV().property("itemid", "Item2")).as("i2").
  coalesce(
    inE("bought").where(outV().as("u")).inV().sack(assign).by("unique_user_bought_count").sack(sum).by(constant(1)).property("unique_user_bought_count", sack()),
    addE("bought").from("u").to("i2").inV().property("unique_user_bought_count", 1)).iterate()

Here's a console test session:

gremlin> user = g.V().has("userid", "ABC").tryNext().orElseGet {
......1>   graph.addVertex("userid", "ABC")
......2> }
==>v[0]

gremlin> g.V(user).as("u").
......1>   coalesce(V().has("itemid", "Item1"), addV().property("itemid", "Item1")).as("i1").
......2>   coalesce(
......3>     inE("bought").where(outV().as("u")).inV().sack(assign).by("unique_user_bought_count").sack(sum).by(constant(1)).property("unique_user_bought_count", sack()),
......4>     addE("bought").from("u").to("i1").inV().property("unique_user_bought_count", 1)).
......5>   coalesce(V().has("itemid", "Item2"), addV().property("itemid", "Item2")).as("i2").
......6>   coalesce(
......7>     inE("bought").where(outV().as("u")).inV().sack(assign).by("unique_user_bought_count").sack(sum).by(constant(1)).property("unique_user_bought_count", sack()),
......8>     addE("bought").from("u").to("i2").inV().property("unique_user_bought_count", 1)).iterate()

gremlin> g
==>graphtraversalsource[tinkergraph[vertices:3 edges:2], standard]
gremlin> g.V().valueMap()
==>[userid:[ABC]]
==>[itemid:[Item1],unique_user_bought_count:[1]]
==>[itemid:[Item2],unique_user_bought_count:[1]]
gremlin> g.E()
==>e[4][0-bought->2]
==>e[8][0-bought->6]

gremlin> g.V(user).as("u").
......1>   coalesce(V().has("itemid", "Item1"), addV().property("itemid", "Item1")).as("i1").
......2>   coalesce(
......3>     inE("bought").where(outV().as("u")).inV().sack(assign).by("unique_user_bought_count").sack(sum).by(constant(1)).property("unique_user_bought_count", sack()),
......4>     addE("bought").from("u").to("i1").inV().property("unique_user_bought_count", 1)).
......5>   coalesce(V().has("itemid", "Item2"), addV().property("itemid", "Item2")).as("i2").
......6>   coalesce(
......7>     inE("bought").where(outV().as("u")).inV().sack(assign).by("unique_user_bought_count").sack(sum).by(constant(1)).property("unique_user_bought_count", sack()),
......8>     addE("bought").from("u").to("i2").inV().property("unique_user_bought_count", 1)).iterate()
gremlin> g
==>graphtraversalsource[tinkergraph[vertices:3 edges:2], standard]
gremlin> g.V().valueMap()
==>[userid:[ABC]]
==>[itemid:[Item1],unique_user_bought_count:[2]]
==>[itemid:[Item2],unique_user_bought_count:[2]]


Cheers,
Daniel


--
You received this message because you are subscribed to the Google Groups "Gremlin-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to gremlin-users+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/gremlin-users/28a0a81b-fa4a-4e75-bb15-f742fe19b27a%40googlegroups.com.

Mitesh Patel

unread,
Jul 25, 2017, 7:17:12 AM7/25/17
to Gremlin-users
Hi Daniel,

Thank you very much for your reply. It helped me achieve the end-result with just a slight tweaking. I tweaked the part where if the user -> bought -> item edge exists then I should just pass. Else, create the edge and (increment the "unique_user_bought_count" by 1 or set it to 1 based on whether that property is present). But ultimately coalesce just worked as expected. Which brings the question of what was wrong with Sack() and Choose() step? Any idea? Why was sack() not able to assign the property only to the last item?

- Regards,
Mitesh
To unsubscribe from this group and stop receiving emails from it, send an email to gremlin-user...@googlegroups.com.

Daniel Kuppitz

unread,
Jul 25, 2017, 10:26:42 AM7/25/17
to gremli...@googlegroups.com
If you send the script as a whole, you need to take care of intermediate result iterations. That means any mutating traversal should end with .iterate().

Cheers,
Daniel


To unsubscribe from this group and stop receiving emails from it, send an email to gremlin-users+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/gremlin-users/29fc17cc-65e6-4d1e-9cbc-7b4781905f47%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages