Does the TinkerGraph in-memory database support List cardinality properties for vertices?

It is my understanding that the following code should work:
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.apache.tinkerpop.gremlin.structure.VertexProperty;
import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph;
import org.junit.jupiter.api.Test;

import java.util.Map;

import static org.apache.tinkerpop.gremlin.process.traversal.AnonymousTraversalSource.traversal;

public class GremlinTest {

@Test
public void testGremlin() {
try (TinkerGraph graph = TinkerGraph.open()) {
GraphTraversalSource g = traversal().withEmbedded(graph);
g.addV("CH")
.property("key", "123")
.property("age", 20)
.property("gender", "male")
.property(VertexProperty.Cardinality.list, "address", "a street, a city")
.property(VertexProperty.Cardinality.list, "address", "b street, b city")
.next();
GraphTraversal<Vertex, Map<Object, Object>> traversal = g.V().hasLabel("CH").elementMap();
while (traversal.hasNext()) {
Map<Object, Object> node = traversal.next();
System.out.printf("%s", node);
}
}
}
}
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.apache.tinkerpop.gremlin.structure.VertexProperty;
import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph;
import org.junit.jupiter.api.Test;

import java.util.Map;

import static org.apache.tinkerpop.gremlin.process.traversal.AnonymousTraversalSource.traversal;

public class GremlinTest {

@Test
public void testGremlin() {
try (TinkerGraph graph = TinkerGraph.open()) {
GraphTraversalSource g = traversal().withEmbedded(graph);
g.addV("CH")
.property("key", "123")
.property("age", 20)
.property("gender", "male")
.property(VertexProperty.Cardinality.list, "address", "a street, a city")
.property(VertexProperty.Cardinality.list, "address", "b street, b city")
.next();
GraphTraversal<Vertex, Map<Object, Object>> traversal = g.V().hasLabel("CH").elementMap();
while (traversal.hasNext()) {
Map<Object, Object> node = traversal.next();
System.out.printf("%s", node);
}
}
}
}
The output when this is executed is:
{id=0, label=CH, address=b street, b city, gender=male, key=123, age=20}
{id=0, label=CH, address=b street, b city, gender=male, key=123, age=20}
However, I would expect its output to be something like this:
{id=0, label=CH, address=["a street, a city", "b street, b city"], gender=male, key=123, age=20}
{id=0, label=CH, address=["a street, a city", "b street, b city"], gender=male, key=123, age=20}
Does anyone know what I am doing wrong here?
Solution:
elementMap() assumes that cardinality for each key is single and if it is list then only the first item encountered will be returned. To get all property values valueMap() step can be used instead. `gremlin> g.V(1).property("address", "a1").property(list, "address", "a2") ==>v[1] gremlin> g.V(1).valueMap()...
Jump to solution
6 Replies
Solution
Valentyn Kahamlyk
Valentyn Kahamlyk•7mo ago
elementMap() assumes that cardinality for each key is single and if it is list then only the first item encountered will be returned. To get all property values valueMap() step can be used instead. gremlin> g.V(1).property("address", "a1").property(list, "address", "a2") ==>v[1] gremlin> g.V(1).valueMap() ==>[address:[a1,a2],name:[marko],age:[29]] gremlin> g.V(1).elementMap() ==>[id:1,label:person,address:a2,name:marko,age:29]
Johan
JohanOP•7mo ago
Thanks for that! This wasted a lot of my time, though...😫 I just checked the javadoc and other documentation and found no mention of this. Is this documented anywhere? I am happy to do it...
ManabuBeach
ManabuBeach•7mo ago
I think in the elementMap description it is documented. Having two similar functions are very confusing.
spmallette
spmallette•7mo ago
the need for two steps arose from the issue where valueMap() creates a structure that is complicated to work with. for the most part, property values are Cardinality.single so for valueMap() to always return a List always tended to confuse folks. we eventually changed valueMap() so that you could do valueMap().by(unfold()) to unwrap the value (which was better than deconstructing and reconstructing the Map), but folks tended to find that unsatisfactory as well because the intent isn't really clear. It was at that point that we decided to do elementMap() so that there was a clear step that explicitly gave folks what they want as output.
ManabuBeach
ManabuBeach•7mo ago
Interesting history. Can’t please everyone :gremlin_smile:
Want results from more Discord servers?
Add your server