user3757753
user3757753

Reputation: 51

Gremlin - sorting group by results

I am grouping vertices by any number of group parameters and I expect the resut to be sorted by those parameters.

Simple test data

g.addV("machine").property("type","PC").property("age",2)
g.addV("machine").property("type","PC").property("age",11)
g.addV("machine").property("type","Mac").property("age",2)
g.addV("machine").property("type","Mac").property("age",2)
g.addV("machine").property("type","Mac").property("age",11)

My prefered output format should look like:

==>[{age=2, type=Mac}]=[{type=[Mac], age=[2]}, {type=[Mac], age=[2]}]
==>[{age=2, type=PC}]=[{type=[PC], age=[2]}]
==>[{age=11, type=Mac}]=[{type=[Mac], age=[11]}]
==>[{age=11, type=PC}]=[{type=[PC], age=[11]}]

or

==>[2, Mac]=[{type=[Mac], age=[2]}, {type=[Mac], age=[2]}]
==>[2, PC]=[{type=[PC], age=[2]}]
==>[11, Mac]=[{type=[Mac], age=[11]}]
==>[11, PC]=[{type=[PC], age=[11]}]

Simply saying: passed grouping parameters and result vertices should be separated.

Upvotes: 1

Views: 500

Answers (2)

stephen mallette
stephen mallette

Reputation: 46216

Gremlin doesn't impose a particular order to the results of traversals. You can rely on the underlying graph implementation and its order semantics but it's often best to just be explicit with the ordering when you can. For that reason I do my group() on an ordered list of properties:

gremlin> g.V().hasLabel("machine").
......1>   group().
......2>     by(properties('age','type').order().by(key).value().fold()).
......3>   order(local).
......4>     by(select(keys).limit(local,1)).
......5>     by(select(keys).tail(local)).next()
==>[2, Mac]=[v[6], v[9]]
==>[2, PC]=[v[0]]
==>[11, Mac]=[v[12]]
==>[11, PC]=[v[3]]

which ensures the "age" comes before the "type" and then I can apply a local order to the resulting Map by just picking apart that property list with limit(), tail(), etc.

Upvotes: 3

user3757753
user3757753

Reputation: 51

I tried couple of solutions:

gremlin> g.V().hasLabel("machine").group().by('age').by(group().by('type').by(valueMap().fold())).unfold()
==>2={PC=[{type=[PC], age=[2]}], Mac=[{type=[Mac], age=[2]}, {type=[Mac], age=[2]}]}
==>11={PC=[{type=[PC], age=[11]}], Mac=[{type=[Mac], age=[11]}]}

This one is sorted, but requires additional postprocessing and I want to suport ordering by any number of parameters in my application logic.

The format is better but not sorted:

gremlin> g.V().hasLabel("machine").order().by("age").by("type").group().by(project("age", "type").by("age").by("type").fold()).by(valueMap().fold()).unfold()
==>[{age=11, type=Mac}]=[{type=[Mac], age=[11]}]
==>[{age=2, type=PC}]=[{type=[PC], age=[2]}]
==>[{age=2, type=Mac}]=[{type=[Mac], age=[2]}, {type=[Mac], age=[2]}]
==>[{age=11, type=PC}]=[{type=[PC], age=[11]}]

The order of group params is not corect, the age should be first:

gremlin> g.V().hasLabel("machine").order().by("age").by("type").group().by(values("age", "type").fold()).by(valueMap().fold()).unfold()
==>[Mac, 2]=[{type=[Mac], age=[2]}, {type=[Mac], age=[2]}]
==>[PC, 2]=[{type=[PC], age=[2]}]
==>[PC, 11]=[{type=[PC], age=[11]}]
==>[Mac, 11]=[{type=[Mac], age=[11]}]

But none of the solutions is what I expected.

Upvotes: 0

Related Questions