Sorting Graph Query Results with Gremlin

2,854 views
Skip to first unread message

James Thornton

unread,
Jun 12, 2011, 1:33:43 PM6/12/11
to gremli...@googlegroups.com
The more I learn Gremlin, the more I see how cool it is. 

Sorting query results is import for stuff like paging. In my quest to learn Gremlin, Stephen, Marko and Pierre helped me figure out this sort thing (https://github.com/tinkerpop/rexster/issues/110), which will allow you do stuff like sort blog entries by published date.

There hasn't always been a good way to do sorting with graphs (http://lists.neo4j.org/pipermail/user/2011-April/008237.html), but Gremlin makes it easy...

g.v(1).out.sort{it.lang}.reverse().toList()

If you run this on the default TinkerGraph data set, it will sort vertex 1's outgoing vertices by language, reverse the results, and return the results as a list. The toList() is important because as Marko said, the Gremlin "pipeline is an iterator and thus, must be iterated" so the toList() converts the iterator to a list. 

Here are docs for all the things you can do with Groovy iterators, including sort(), reverse(), and toList(): http://groovy.codehaus.org/groovy-jdk/java/util/Iterator.html

Thanks guys for your help!

- James

Marko Rodriguez

unread,
Jun 12, 2011, 2:36:01 PM6/12/11
to gremli...@googlegroups.com
Hi,

One thing to be wary about when using native Groovy methods. They do not returns Pipes, but iterators, iterables, etc. As such, to convert one of these objects back into a Pipeline flow, use _.

gremlin> g.v(1).out.sort{it.lang}.reverse()               
==>v[3]
==>v[4]
==>v[2]
gremlin> g.v(1).out.sort{it.lang}.reverse().outE    
No such property: outE for class: org.codehaus.groovy.runtime.ReverseListIterator
Display stack trace? [yN] 
gremlin> g.v(1).out.sort{it.lang}.reverse().class
==>class org.codehaus.groovy.runtime.ReverseListIterator
gremlin> g.v(1).out.sort{it.lang}.reverse()._().outE
==>e[10][4-created->5]
==>e[11][4-created->3]

Get it?,
Marko.

James Thornton

unread,
Jun 12, 2011, 2:59:34 PM6/12/11
to gremli...@googlegroups.com
Thanks Marko. 

So in this case it would make sense to call sort() and reverse() last (after outE) to limit conversions. 

Also, I believe it's better to always call toList() as the very last command because it's more efficient to do sort() and reverse() as an iterator than to perform those operations after it's copied to a list because then you're copying lists around and are not getting the memory-management benefits of iterators. 

James Thornton

unread,
Jun 12, 2011, 3:15:09 PM6/12/11
to gremli...@googlegroups.com
So you would write that as....

g.v(1).out.outE.back(1).sort{it.lang}.reverse().toList()

NewtoGremlin

unread,
Jun 7, 2015, 11:57:29 AM6/7/15
to gremli...@googlegroups.com
Hi!

This is great thanks!

I was wondering if it is possible to sort the results on the basis of values in another linked vertex and print both vertices along with the sorted values.
So for example, 
If products have labels and I want to sort all products as per their labels and then print the product and the label.

My idea was to do this:

sorted=product._().as('z').outE.has('edgeLabel', 'label').inV.sort{it.vertexProperty}._().back('z').toList()

--> null Pointer exception

sorted._().outE.filter{it.edgeLabel=='label>'}.inV.path{it.vertexProperty}{it.edgeLabel}{it.vertexProperty}


any ideas what I can do?

Reply all
Reply to author
Forward
0 new messages