I need to write a single Gremlin query that can set the new property values of a vertex. All the property names are known in advance (in this example: Type, Country, Status). Some of the property values can be null - and I don't know which ones in advance. The query should work for all cases. For example, let's say I currently have this query:
g.V(123).
property('Type',Type).
property('Country',Country).
property('Status',Status)
This query works fine if all the parameter (Type, Country, Status) values are non-null. If, say, Country is null, I get an error:
The AddPropertyStep does not have a provided value: AddPropertyStep({key=[Country]})
In such case I would need to use a different query to drop the property (by the way, is there a better way for dropping a property?):
g.V(123).
property('Type',Type).
property('Status',Status).
properties('Country').drop()
Is it possible to write a universal query that can handle both null and non-null values? I cannot use console or programming, just a single Gremlin query to be executed.
Thanks!
TinkerPop doesn't allow null
values in properties (though you might find some graph databases allowing different semantics there, I suppose), so you should validate your data up front to ensure that it has some meaningful "empty value" as opposed to a null
. If you can't do that for some reason, I guess you could use choose()
step to "check for null":
gremlin> g = TinkerFactory.createModern().traversal()
==>graphtraversalsource[tinkergraph[vertices:6 edges:6], standard]
gremlin> g.V().has('person','name','marko').valueMap()
==>[name:[marko],age:[29]]
gremlin> age = null
gremlin> g.V().has('person','name','marko').choose(constant(age).count().is(0), properties('age').drop(),property('age',age))
gremlin> g.V().has('person','name','marko').valueMap()
==>[name:[marko]]
gremlin> age = 30
==>30
gremlin> g.V().has('person','name','marko').choose(constant(age).count().is(0), properties('age').drop(),property('age',age))
==>v[1]
gremlin> g.V().has('person','name','marko').valueMap()
==>[name:[marko],age:[30]]
The check for "is null" is basically just: constant(age).count().is(0)
, which leans on the Gremlin's semantics for null
values in a stream being empty and giving a count()
of zero. It works, but it makes your Gremlin a little less readable. That might be a nice DSL step to add if you have to write that a lot.