Search code examples
javaspring-bootgremlinamazon-neptune

Empty vertex properties with Java and Gremlin


I'm writing a database adapter to work with Amazon Neptune database in Spring Boot. I want to return a custom datatype instead of Vertex, or list of Vertex in search cases. So when I execute a search I have to map found vertices to my custom class.

For the step I'm in (just writing Vertex data into console) I just need to get each node's Id, label and properties but I always get empty properties.

I have this sample graph:

sample data graph

I'm calling the method using key = "city", value = "Malaga". This returns two nodes.

Approach 1:

public void queryNodesByProperty(String key, String value) throws Exception {
    if(key == null || key.trim().length() == 0) throw new Exception("Key cannot be empty");

    List<TreeNode> result = g.V().has(key,value).toList().stream().map(e->{

        System.out.println(e.id());    //works
        System.out.println(e.label()); //works
        System.out.println(e.properties());        //returns java.util.Collections$EmptyIterator
        System.out.println(e.property("name"));    //returns empty
        System.out.println(e.properties().next()); //Throws NoSuchElementException
            
        //I will call my mapper here
        return TreeNodeMapper.getTreeNode(e);
    }).collect(Collectors.toList());
}

Approach 2: For now on, I just try to output data

public void queryNodesByProperty(String key, String value) throws Exception {
        if(key == null || key.trim().length() == 0) throw new Exception("Key cannot be empty");

        Stream<Vertex> s = g.V().has(key,value).toStream();
        s.forEach(v -> {
            System.out.println(v.id());    //works
            System.out.println(v.label()); //works
            System.out.println(v.property("city")); //returns vp[empty]
            System.out.println(v.keys()); //returns []
        });
    }

Approach 3: Just output data

public void queryNodesByProperty(String key, String value) throws Exception {
        if(key == null || key.trim().length() == 0) throw new Exception("Key cannot be empty");

        List <Vertex> l = g.V().has(key,value).toList();
        l.forEach(v -> {
            System.out.println(v.id());    //works
            System.out.println(v.label()); //works
            System.out.println(v.property("city")); //returns vp[empty]
            System.out.println(v.keys()); //returns []
        });
    }

Any help appreciated. Thanks!


** UPDATE **

As @taylor-riggan and @kelvin-lawrence suggested I updated my code to iterate the result of elementMap() instead of trying to iterate vertices collection.

List<Map<Object,Object>> ln = g.V().has(key,value).elementMap().toList();
System.out.println(ln);
ln.forEach(ve->{
    System.out.println(ve.get("id"));
    System.out.println(ve.get("label"));
    System.out.println(ve.get("area"));
});

This outputs:

[{id=30c21e3b-31fa-2e27-43b5-7ea2e78545b6, label=Person, name=Peter, town=Marbella, city=Malaga, area=Andalucia}, {id=b4c21e3b-32a8-972a-8623-26fa165e63e3, label=Person, name=Victor, town=Torremolinos, city=Malaga, area=Andalucia}]
null
null
Andalucia
null
null
Andalucia

As you said, id and label are present in each element, but when I try to get the value I still get null. That is what took me to experiment iterating vertices.

I see this when I debug the code and inspect the map for an element: map inspection

So id and label keys are somehow "special" and cannot get them using .get("id")

How can i get those values?

Thanks


Solution

  • Currently, as of 3.6.x, properties are not returned on graph elements and you must therefore transform a Vertex or Edge to a Map with steps like project(), elementMap(), etc. If you are interested, the reasons and history for this design decision are described here.

    To get the ID and label from a Map, note that the keys for these values are not String but of type T so you would want to access them as T.id or T.label respectively.

    Finally, there is work currently underway for 3.7.x to allow you to shape the properties returned in graph element so eventually you would be able to work directly with Vertex and Edge instances and their properties.