need some tips/advise on a gremlin query ... :)
I have these types of vertices ...
orders: id, cid (string), ts (long)
// predicates for the orders
ip: id
phone: id
// few more
and Edges go from predicates to orders:
ip -- ip_used_in --> order
phone -- ph_used_in --> order
// few more from predicates to orders
Now i want to insert an order vertex and the corresponding ip and phone vertices if they are not present and add the edge between them.
I have got first part working using the fold + coalesce pattern. But it adds parallel edges if edge already exists.
// inserting o3, ip1 and ph1 if not present and adding edge between them
g.
V("o3").fold().coalesce(unfold(),addV("order").property(id, "o3").property("ts", 11).property("cid", "c1")).
sideEffect(addE('ip_used_in').from(V('ip1').fold().coalesce(unfold(), addV("ip").property(id, "ip1")))).
sideEffect(addE('ph_used_in').from(V('ph1').fold().coalesce(unfold(), addV("ph").property(id, "ph1")))).
// ... few more predicates omitted
iterate()
Now i'm stuck at an additional condition : add the edge between order and ip/phone/predicate if there doesn't exist any other edge to an order having same cid, with greater or equal ts. if some order exists with same cid but lesser ts, drop that edge and add the new one. Because of the fold i cannot refer to conditionally added order vertex in the beginning.
Essentially i want to only have the latest order (max ts) connected to the predicates (ip, phone, ... etc) per cid.
So Q1. How to nest conditions/side-effects to conditionally add a vertex and link an edge to it based on another condition ?
Q2. Is the effect of the SideEffect visible in later parts of the traversal ? didnt seem to find the info in gremlin reference.
Sample code to test in gremlin consiole:
// create initial state
// o1, ip1, ph1
// o2, ip2, ph1
g.
addV("order").property(id, "o1").property("ts", 10).property("cid", "c1").as("o1").
addV("order").property(id, "o2").property("ts", 9).property("cid", "c2").as("o2").
addV("ip").property(id, "ip1").as("ip1").
addV("ip").property(id, "ip2").as("ip2").
addV("ph").property(id, "ph1").as("ph1").
addE("ip_used_in").from("ip1").to("o1").
addE("ip_used_in").from("ip2").to("o2").
addE("ph_used_in").from("ph1").to("o1").
addE("ph_used_in").from("ph1").to("o2").
iterate()
// try different scenarios
// try to add o1 again, no exception but in tinkergraph got duplicate edges between o1 - ip1 and o1 - ph1
g.
V("o1").fold().coalesce(unfold(),addV("order").property(id, "o1").property("ts", 11).property("cid", "c1")).
sideEffect(addE('ip_used_in').from(V('ip1').fold().coalesce(unfold(), addV("ip").property(id, "ip1")))).
sideEffect(addE('ph_used_in').from(V('ph1').fold().coalesce(unfold(), addV("ph").property(id, "ph1")))).
iterate()
// how to remove existing edges between o1 - ip1 and o1 - ph1 ?
g.
V("o3").fold().coalesce(unfold(),addV("order").property(id, "o3").property("ts", 11).property("cid", "c1")).
sideEffect(addE('ip_used_in').from(V('ip1').fold().coalesce(unfold(), addV("ip").property(id, "ip1")))).
sideEffect(addE('ph_used_in').from(V('ph1').fold().coalesce(unfold(), addV("ph").property(id, "ph1")))).
iterate()
// how to avoid adding edges since later orders exist from same cid = c1 against ip1 and ph1 ?
g.
V("o0").fold().coalesce(unfold(),addV("order").property(id, "o0").property("ts", 0).property("cid", "c1")).
sideEffect(addE('ip_used_in').from(V('ip1').fold().coalesce(unfold(), addV("ip").property(id, "ip1")))).
sideEffect(addE('ph_used_in').from(V('ph2').fold().coalesce(unfold(), addV("ph").property(id, "ph2")))).
iterate()