What is the gremlin query for sorting by putting empty values at the bottom - gremlin

I am trying to find an equivalent for the below SQL query in the Gremlin query.
select * from test.test_table order by alias = '', alias asc, name asc;
The above query does the sorting based on ascending order by putting empty rows at the bottom.
In the Gremlin query, I am trying to write the below query but alias property with empty values are coming at the top.
I want to have proper sorting for the alias field but empty and null values should go at the bottom.
g.V("ID").inE('RELATIONSHIP_NAME').outV().order().by('alias', asc).by('name', asc).valueMap().toList()
Thank you.

You can work around this limitation by doing:
g.V("ID").inE('RELATIONSHIP_NAME').outV().
order().
by(values('alias').choose(within(['', null]), constant('zzz'), identity())).
by('name').
valueMap().toList()
A working example using the Modern TinkerGraph:
gremlin> graph = TinkerFactory.createModern()
==>tinkergraph[vertices:6 edges:6]
gremlin> g=graph.traversal()
==>graphtraversalsource[tinkergraph[vertices:6 edges:6], standard]
gremlin> g.addV('person').property('name', '').property('age',33)
==>v[13]
gremlin> g.addV('person').property('name', '').property('age',23)
==>v[16]
gremlin> g.V().order().by(values('name').choose(within(['', null]), constant('z'), identity())).by('age').values('name')
==>josh
==>lop
==>marko
==>peter
==>ripple
==>vadas
==>
==>

I somehow found the correct answer which is working.
g.V("ID").
inE('RELATIONSHIP').
outV().
order().
by(choose(values('alias').is(''),constant(1), constant(0)), asc).
by('alias', asc).by('name', asc).range(0,-1).valueMap()

Related

Update a vertex property with another property value in Cosmos Gremlin API

I would like to move a property value to another property in all vertex using gremlin query.
g.V('test').property('id','1').property('name','a').property('new_name','aa')
g.V('test').property('id','2').property('name','b').property('new_name','bb')
g.V('test').property('id','3').property('name','c').property('new_name','cc')
I would like to update name property with value from new_name property of the same vertex and delete new_name property.
You can do something like this
gremlin> g.addV('test').property('id','1').property('name','a').property('new_name','aa').
......1> addV('test').property('id','2').property('name','b').property('new_name','bb').
......2> addV('test').property('id','3').property('name','c').property('new_name','cc')
==>v[61405]
gremlin> g.V().valueMap()
==>[name:[a],id:[1],new_name:[aa]]
==>[name:[b],id:[2],new_name:[bb]]
==>[name:[c],id:[3],new_name:[cc]]
gremlin> g.V().property(single,'name',values('new_name')).properties('new_name').drop()
gremlin> g.V().valueMap()
==>[name:[aa],id:[1]]
==>[name:[bb],id:[2]]
==>[name:[cc],id:[3]]

gremlin - how to update vertex property with another vertex's property

testing data:
vertex A has property 'a' value '1'
vertex B has outEdge 'e' to A
vertex B had property 'b' value '2'
how do I update 'a' to be value from 'b' in this case '2'?
I have tried this but not working
g.V().hasLabel('A').property('a', inE('e').outV().project('b').by('b').unfold())
Building the graph using...
gremlin> g.addV('A').property('a','1').as('a').
......1> addV('B').property('b','2').as('b').
......2> addE('e').from('b').to('a')
gremlin> g.V().valueMap()
==>[a:[1]]
==>[b:[2]]
You can use values from A to update B as follows (this is one way to write the query, there are alternative ways)
gremlin> g.V().hasLabel('B').as('b').V().hasLabel('A').property('a',select('b').values('b'))
==>v[42790]
gremlin> g.V().valueMap()
==>[a:[2]]
==>[b:[2]]

Gremlin Neptune - order by a property which doesn't exist in all vertices

Assumuing I have a graph with 'person' vertices.
Each vertex have a 'name' and 'age' properties, except of one.
Now I'm trying to order by age:
g.V().order().by('age', asc).valueMap()
But it fails:
"The property does not exist as the key has no associated value for the provided element: v[328]:age"
Check this out: https://gremlify.com/ybbfwd2hbbc
How can I "replace" the missing properties with, let's say, 0? Thanks!
You can use constant to fill out the missing values:
g.V().
order().
by(coalesce(
values('age'),
constant(0)
), asc).
valueMap()
example: https://gremlify.com/qqhym71jlg
Or filter them ahead:
g.V().
.has('age')
order().
by('age', asc).
valueMap()
Example: https://gremlify.com/qqhym71jlg/1

Gremlin Order by latest Date

I added vertices with createDate as a property. I want to retrieve the latest created vertex using createDate property.
How can I retrieve this. Please help me with this.
Just order() your vertices in descending order by the createDate and grab the first one:
gremlin> g = TinkerGraph.open().traversal()
==>graphtraversalsource[tinkergraph[vertices:0 edges:0], standard]
gremlin> g.V().order().by('createDate', desc).limit(1)
==>v[2]
gremlin> g.V().order().by('createDate', desc).limit(1).values('createDate')
==>22-OCT-2019

How to search multiple values for same propertykey in gremlin

What is the best way to get values with same property key?
EDIT: Sorry for changing the question my requirement was to get an employee from either of the departments
I need to fetch all the the employees who work for IT or Sales departments and are being managed by manager with id 123.
I have used
g.V().has('managerId',123).out('manages').as('employee')
.out('worksFor').has('departmentName','IT','Sales')
.select('employee')
where out('worksAt') gives department.
Can we do this in a has() step or should we use union() step like
g.V().has('managerId',123).out('manages').as('employee').out('worksFor')
.union(__.has('departmentName','IT'),__.has('departmentName','Sales')
.select('employee')
You are probably only missing the within predicate which is also explained in the context of the has step in the TinkerPop documentation:
g.V().has('managerId',123).out('manages').as('employee').out('worksFor').
has('departmentName',within('IT','Sales')).select('employee')
edit: After reading stephen's answer I noticed that I read over the and in your question:
employees who work for IT and Sales
That makes my answer of course invalid. I still leave it here just in case that you actually meant or as indicated by your later use of the union step.
Here's a sample graph:
gremlin> graph = TinkerGraph.open()
==>tinkergraph[vertices:0 edges:0]
gremlin> g = graph.traversal()
==>graphtraversalsource[tinkergraph[vertices:0 edges:0], standard]
gremlin> g.addV("managerId",123).as("manager").
......1> addV("employee","A").as("A").
......2> addV("employee","B").as("B").
......3> addV("department", "IT").as("it").
......4> addV("department", "Sales").as("sales").
......5> addE("manages").from("manager").to("A").
......6> addE("manages").from("manager").to("B").
......7> addE("worksFor").from("A").to("it").
......8> addE("worksFor").from("B").to("it").
......9> addE("worksFor").from("A").to("sales").iterate()
In this case, I make it so that employee A is in both "Sales" and "IT", but employee B is only in "IT". Since you said you wanted employees who work in both departments employee A is who should be returned from the query and B should be filtered out.
Note that the use of within yields an incorrect answer in that case:
gremlin> g.V().has('managerId',123).
......1> out('manages').
......2> where(out('worksFor').
......3> has('department',within('IT','Sales'))).
......4> valueMap()
==>[employee:[A]]
==>[employee:[B]]
Here is the approach if you want both departments:
gremlin> g.V().has('managerId',123).
......1> out('manages').
......2> where(out('worksFor').
......3> has('department','Sales')).
......4> where(out('worksFor').
......5> has('department','IT')).
......6> valueMap()
==>[employee:[A]]

Resources