Bringing together the Apache Cassandra experts from the community and DataStax.

Want to learn? Have a question? Want to share your expertise? You are in the right place!

Not sure where to begin? Getting Started

 

question

rickpaiste_111833 avatar image
rickpaiste_111833 asked ·

What is the gremlin recipe to use traversal induced values in the predicate of a __.has( ,,) step?

Hi ! @bettina.swynnerton. Denise suggested that I post this question to your attention.

DSE 6.7 Graph - what is the gremlin recipe to use traversal induced values in the predicate of a __.has( ,,) step

I am able to successfully execute the following traversal:

g.V().hasId("{cluster_key=\"kjjwg\", cluster_key2=\"1234\", ~label=widget, partition_key=\"57992577731\"}").as("srcW")
  .union(
    __.V().has("widget","property1",eq("xxx")), // property1 is indexed. The explicit value "xxx" is equal to select("srcW").values("property1")
    __.V().has("widget","property2",eq("abc")), // property2 is indexed. The explicit value "abc" is equal to select("srcW").values("property2")
    __.V().has("widget","property3",eq("123")) // property3 is indexed. The explicit value "123" is equal to select("srcW").values("property3")
  ).where(P.neq("srcW")).dedup()

I would like to be able to dynamically assign values to the has() steps for property1, property2, property3 from the "srcW) save point in a single traversal instead of executing 2 separate traversals from client to server.

I have tried variants of https://tinkerpop.apache.org/docs/current/recipes/#traversal-induced-values to no avail.

The target environment is the DSE Graph Fluent Java API.

Thank you

dsegraph
1 comment
10 |1000 characters needed characters left characters exceeded

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

Hi @rickpaiste_111833,

I hope I can help. I'll need to do some research and experiments, bear with me.

0 Likes 0 · ·

1 Answer

bettina.swynnerton avatar image
bettina.swynnerton answered ·

Hi @rickpaiste_111833,

if I understand you correctly, you would like to look up all the vertices in the graph that share certain property values with the seed vertex "srcW", but are not the seed vertex itself.

I used the simple test graph that is mostly used in these traversal recipes and added a bit more data so that this search would return meaningful values. I also allowed scans for this quick test, you will need to set up search indexes where applicable to avoid scans.

My vertices look now like this:

gremlin> g.V().valueMap()
==>{software_id=[software1], name=[lop], lang=[java]}
==>{software_id=[software2], name=[ripple], lang=[java]}
==>{name=[josh], age=[32], person_id=[person3]}
==>{name=[anna], age=[29], person_id=[person10]}
==>{name=[vadas], age=[27], person_id=[person2]}
==>{name=[marko], age=[30], person_id=[person11]}
==>{name=[marko], age=[29], person_id=[person1]}
==>{name=[peter], age=[35], person_id=[person4]}

The following traversal looks up all vertices in the graph of label "person" that have the same value for the property "age" or the same value for the property "name" as the seed vertex "marko", but are not "marko".

g.V().has('person', 'person_id','person1').as('marko').
union(
__.V().hasLabel("person").as('friend1').where('friend1', eq('marko')).by('age'), __.V().hasLabel("person").as('friend2').where('friend2', eq('marko')).by('name')
).
where(P.neq("marko")).dedup()


Here is the output from Gremlin console:

gremlin> g.V().has('person', 'person_id','person1').as('marko').
......1> union(
......2> __.V().hasLabel("person").as('friend1').where('friend1', eq('marko')).by('age'), __.V().hasLabel("person").as('friend2').where('friend2', eq('marko')).by('name')
......3> ).
......4> where(P.neq("marko")).dedup()
==>v[{~label=person, person_id="person10"}]
==>v[{~label=person, person_id="person11"}]

I hope this helps!

5 comments Share
10 |1000 characters needed characters left characters exceeded

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

[Re-posted comment into original question since it's not an answer]

0 Likes 0 · ·

I suspect that the solution will require 2 traversals. This is sequence of operation does work:

matchProperties = g.V().hasId('{cluster_key="kjjwg", cluster_key2="1234", ~label=widget, partition_key="57992577731"}').project("vId","prop1", "prop2", "prop3") .by(values("property1")) .by(values("property2")).by(values("property3")).next()

propValue1 = matchProperties["prop1"]

propValue2 = matchProperties["prop2"]

propValue3 = matchProperties["prop3"]

0 Likes 0 · ·

g.V().hasId('{cluster_key="kjjwg", cluster_key2="1234", ~label=widget, partition_key="57992577731"}').as("srcW").union( __.V().has("widget","property1",propValue1), __.V().has("widget","property2",propValue2), __.V().has("widget","property3",propValue3)).where(P.neq("srcW")).dedup()

However that will require multiple I/O operations to the server.

0 Likes 0 · ·

Hi @bettina.swynnerton - thank you for the prompt response. I tried the solution on my target graph but encountered an exception.

Here is the modified traversal:

g.V().hasId('{cluster_key="kjjwg", cluster_key2="1234", ~label=widget, partition_key="57992577731"}').as("srcW").union(
  __.V().hasLabel("widget").as("otherW").where("otherW",eq("srcW")).by("property1"),
  __.V().hasLabel("widget").as("otherW").where("otherW",eq("srcW")).by("property2"),
  __.V().hasLabel("widget").as("otherW").where("otherW",eq("srcW")).by("property3")
).where(P.neq("srcW")).dedup()
0 Likes 0 · ·

However the traversal throws the following exception:

java.lang.UnsupportedOperationException: Could not find an index on vertices labeled 'widget' to answer the condition: '((label = widget))'. Current indexes are: widgetByProperty3(Materialized)->property3, widgetByProperty2(Materialized)->property2, widgetByProperty1(Materialized)->property1d. Alternatively if in development enable graph scan by using graph.allow_scan. Graph scan is NOT suitable for anything other than toy graphs.
0 Likes 0 · ·