0

Goal: I am trying to add a bunch of vertices and edges in a single traversal and return a subset of those.

It might be that the fluent API is still in Beta or that I haven't understood the API properly:

I think there is a problem with .select() and GraphResultSet one() and all() but here is what I have tried:

GraphTraversal<Vertex,Vertex> traversal = g.addV("Entity").property("uuid","testuuid").as("a")
            .addV("Entity").property("uuid","testuuid3").as("b");
            GraphStatement graphStatement =  DseGraph.statementFromTraversal(traversal.select("a","b"));
            GraphResultSet grs = dseSession.executeGraph(graphStatement.setGraphName("graph"));

I am creating two vertices a,b and I select both of them.. if I select only one grs.one().as(Vector.class) works fine... but now that I select both a and b ... grs.one() and grs.all() return both results in a list [] and in an obj {} .. iterator() doesn't work properly since grs.all().count() is 1.. so I can't get what I need .. assuming that grs.all() returns an iterator for two things and grs.one() returns the first thing.

grs.all() returns something like that:

[{a=DefaultVertex{id={~label=Entity, community_id=903802240, member_id=515}, label=Entity, properties=com.google.common.collect.Iterators$3@3670f00}, b=DefaultVertex{id={~label=Entity, community_id=903802240, member_id=516}, label=Entity, properties=com.google.common.collect.Iterators$3@452e26d0}}]

grs.one() returns something like that:

{a=DefaultVertex{id={~label=Entity, community_id=1220980480, member_id=514}, label=Entity, properties=com.google.common.collect.Iterators$3@10b892d5}, b=DefaultVertex{id={~label=Entity, community_id=1220980480, member_id=515}, label=Entity, properties=com.google.common.collect.Iterators$3@3d3f761a}}

Edit (trying to iterate over multiple things in the same row (see comments):

   GraphNode ga = grs.all().iterator().next(); // this contains both a and b 
   System.out.println(ga.getClass()); // this is ObjectGraphNode :/

I am using:

<dependency>
   <groupId>com.datastax.cassandra</groupId>
   <artifactId>dse-driver</artifactId>
   <version>1.1.1-beta1</version>
</dependency>
<dependency>
   <groupId>com.datastax.cassandra</groupId>
   <artifactId>java-dse-graph</artifactId>
   <version>1.0.0-beta1</version>
</dependency>

Any help is appreciated!

Michail Michailidis
  • 11,792
  • 6
  • 63
  • 106

1 Answers1

2

I'm not sure what your expectation is, but select("a","b") is supposed to return both vertices in a single "row". Both results, for all() and one(), look good to me.

Here's a wild guess; you're probably looking for something like this:

g.addV("Entity").property("uuid","testuuid").union(identity(),
  addV("Entity").property("uuid","testuuid3"))

This traversal would create 2 vertices and return them in 2 separate rows.

UPDATE

After figuring out, in the comments below, that the use-case was to iterate over the map entries returned in a GraphNode (which is a wrapper for any object returned by the DSE Graph API), the answer should be one of the following.

If you only need the first vertex:

executeGraph(statementFromTraversal(
  g.addV("Entity").property("uuid","testuuid").sideEffect(
    addV("Entity").property("uuid","testuuid3"))).one().asVertex()

If you only need the second vertex:

executeGraph(statementFromTraversal(
  g.addV("Entity").property("uuid","testuuid").
    addV("Entity").property("uuid","testuuid3")).one().asVertex()

If you need all / multiple vertices:

GraphNode n = executeGraph(statementFromTraversal(
  g.addV("Entity").property("uuid","testuuid").as("a").
    addV("Entity").property("uuid","testuuid3").as("b").select("a","b")).one()
n.get("a").asVertex() // work w/ vertex a
n.get("b").asVertex() // work w/ vertex b
Daniel Kuppitz
  • 10,846
  • 1
  • 25
  • 34
  • The question then is how can I iterate the two and why .one() doesn't return only the first one – Michail Michailidis Dec 21 '16 at 19:08
  • There is only one result, hence `one()` and `all()` return the same thing. The difference is, that `all()` is usually used for traversals that are expected to return more than one row, hence it's a list. – Daniel Kuppitz Dec 21 '16 at 19:49
  • I see! Yeah your update makes sense that's what I wanted :) – Michail Michailidis Dec 21 '16 at 19:53
  • I tried ```g.addV("User").as("a").union(g.addV("User").as("b"))``` and then I still get 1 with ```grs.all().size()``` ! – Michail Michailidis Dec 21 '16 at 19:55
  • 1
    Don't modify my traversal :). There's only 1 `g`. – Daniel Kuppitz Dec 21 '16 at 19:56
  • I need to use this weird _. I guess? iterator worked though with the wrong one :/ – Michail Michailidis Dec 21 '16 at 19:57
  • If you don't have the steps statically imported, then yes, you'll have to use `__.addV(...)`. – Daniel Kuppitz Dec 21 '16 at 20:01
  • Sorry, I just noticed that there was a bug in my traversal. Fixed. – Daniel Kuppitz Dec 21 '16 at 20:01
  • thanks! So if I have one row with many things as I had in the first query there is no way to iterate through its contents right? – Michail Michailidis Dec 21 '16 at 20:06
  • 1
    Well, you need to be aware of the element type. `select("a","b")` will emit `Map`s. You can take the first map and then do something like `map.entrySet()` in your java app to get an iterator over all entries. – Daniel Kuppitz Dec 21 '16 at 20:13
  • Maybe I just don't get what you use-case is. If you want to create the 2 vertices, but only want to get the first one in the result, then the most effective way to do that, is probably this: `g.addV("Entity").property("uuid","testuuid").sideEffect(addV("Entity").property("uuid","testuuid3"))`. – Daniel Kuppitz Dec 21 '16 at 20:31
  • the comment above (about the map) answers my question but I can't find a clean way to do it in Java.. please check my edit I can't find how to get a map in Java out of it :/ it still doesn't make sense why a GraphNode contains both a and b! – Michail Michailidis Dec 21 '16 at 20:58
  • 1
    See https://github.com/datastax/java-dse-graph/blob/1.x/java-dse-graph/src/test/java/com/datastax/dse/graph/statement/TraversalIntegrationTest.java#L145. `result.fieldNames()` will give you all the keys (`a` and `b` in your example) and `result.get(key)` will return the value for a specific key. – Daniel Kuppitz Dec 21 '16 at 21:08
  • It's still not optimal what you do there. Do you need the first vertex (`a`) or the second vertex (`b`)? I can provide a better solution for both cases. However, if you need both vertices and just want to access them separately, there'll be yet another way to do it. Just let me know what you'll ultimately need. – Daniel Kuppitz Dec 21 '16 at 22:06
  • Got it.. I was able to do it like that: ```g.addV("User").as("a").addV("User").as("b").select("a","b").next().get("b")``` Once again it is because you were speaking Gremlin API, and I thought I did too .. but according to http://stackoverflow.com/q/41261845/986160 I was talking DSE API since I was using executeGraph :/ Please change your answer so I can accept - keep the wild guess too :) – Michail Michailidis Dec 21 '16 at 22:07
  • What I am ultimately trying to do: is have a traversal that I am doing a bunch of additions of vertices and edges at once and then return only a small subset of those when I say .next() or toList() which causes the graph to be stored – Michail Michailidis Dec 21 '16 at 22:08
  • 1
    Ha, ok, I'll add all use-cases to my answer. – Daniel Kuppitz Dec 21 '16 at 22:08
  • Cool I changed my question and the description a bit to fit better – Michail Michailidis Dec 21 '16 at 22:14
  • One last question how can I make this work without cast and using just Gremlin API ```Vertex v = g.addV("User").as("a").addV("User").as("b").select("a","‌​b").next().get("b");``` ? ```get("b")``` is trying to return Object – Michail Michailidis Dec 21 '16 at 22:18
  • 1
    You can provide a hint that `select` will only select objects of type `Vertex`: `Vertex v = g.addV("User").as("a").addV("User").as("b").select("a","‌​b"‌​).next().get("b");` – Daniel Kuppitz Dec 21 '16 at 22:23
  • Awesome Thanks! Have a good day/night :) I was trying select("a","b") as if it were C# :p – Michail Michailidis Dec 21 '16 at 22:28
  • 1
    Ha, get used to it. It ALWAYS happens to me after writing a bit of C# code and I wonder if somebody changed the API :). – Daniel Kuppitz Dec 21 '16 at 22:30
  • Sorry to bug you again.. what if some edges/vertices are not there? I am getting NoSuchElementExceptions :/ (this seems outdated: http://stackoverflow.com/q/27704043/986160 and I couldn't do it with map). Any chance you know how to do it with Gremlin 3.0? – Michail Michailidis Dec 23 '16 at 11:40
  • 1
    There's an `optional()` step in Gremlin 3. If this info alone doesn't help, then better open a new question, providing an example of what exactly you're trying to do. – Daniel Kuppitz Dec 23 '16 at 12:24
  • http://stackoverflow.com/q/41304450/986160 I made a broader question - Thanks in advance - I am thinking of a bounty too :) – Michail Michailidis Dec 23 '16 at 16:00