pietermartin / sqlg

TinkerPop graph over sql
MIT License
246 stars 51 forks source link

How do I due simple group by queries within Java? #279

Closed bshambaugh closed 6 years ago

bshambaugh commented 6 years ago

In postgres I have:

SELECT name, SUM(age) FROM "public"."V_Person" GROUP BY name;

name | sum
-------+------ peter | 1085 vadas | 837 marko | 899 josh | 2077 (4 rows)

The closest I got in Gremlin to emulating this was: List persons = g.traversal().V().hasLabel("Person").group().by("name").by("age").toList();

[{peter=[35, 35, 35, ... , 35, 35], vadas=[27, 27, 27, ..., 27, 27], josh=[32, 35, ... , 32, 35], marko=[29, 29, ... , 29, 29]}]

I thought perhaps I could do something like*:

List persons = g.traversal().V().hasLabel("Person").group().by("name").by(values("age").sum()).toList();

however, I am confused how to use values() in this context as "age" is being treated as a string

*as hinted at in "IV GROUP BY and ORDER BY translation" in https://academy.datastax.com/content/sql-tpo-p .

"What we want is not to order the items inside the Iterator but to order the entries inside each Map. For that we need to use the local keyword" (https://academy.datastax.com/content/sql-tpo-p )

I note in Java, local is Scope.local .

Perhaps I am getting confused by streams, and how the values are being passed around.

pietermartin commented 6 years ago

Here is what I have,

loading TinkerPop's modern graph twice,

@Test
public void test() {
    loadModern();
    loadModern();
    List<Map<Object, Object>> vertices = this.sqlgGraph.traversal().V().hasLabel("person")
        .group().by("name").by(__.values("age").sum())
        .toList();
    System.out.println(vertices);
}

and the output

[{peter=70, vadas=54, josh=64, marko=58}]

And loadModern for interest,

    protected void loadModern(SqlgGraph sqlgGraph) {
        Io.Builder<GraphSONIo> builder = GraphSONIo.build(GraphSONVersion.V3_0);
        final GraphReader reader = sqlgGraph.io(builder).reader().create();
        try (final InputStream stream = AbstractGremlinTest.class.getResourceAsStream("/tinkerpop-modern-v3d0.json")) {
            reader.readGraph(stream, sqlgGraph);
        } catch (IOException e) {
            Assert.fail(e.getMessage());
        }
    }

Sqlg does not yet optimize group by statements. i.e. the grouping is done by TinkerPop.

Its a //TODO once version 2 is out.