How to use a UUID as id in Gremlin? - gremlin

I'm adding verticles like this:
g.addV("foobar").property("id", 1).property(...etc...
How can I set a property with a uuid instead of an integer id?

An "id" can have multiple meanings. If you simply mean that you want to use a UUID as a unique identifier to lookup your vertices then taking the approach you have is fine, when used in conjunction with the underlying indexing functionality of your chosen graph database. In other words, as long as you have an index on "id" then you will quickly find your vertex. In this sort of usage, "id" is really just a property of the vertex obviously and you may find that for certain graph databases that "id" is actually a reserved term and can't be used as a property key. It is likely best to choose a different key name.
If instead of using "id" as a property key, you mean that you wish to set the actual vertex identifier, referred to by T.id, as in:
g.addV(T.id, uuid)
then you first need to use a graph database implementation that allows the assignment of identifiers. TinkerGraph is one such implementation. In this way, you natively assign the identifier of the vertex rather than allowing the graph database to create it for you.
gremlin> graph = TinkerGraph.open()
==>tinkergraph[vertices:0 edges:0]
gremlin> g = graph.traversal()
==>graphtraversalsource[tinkergraph[vertices:0 edges:0], standard]
gremlin> g.addV(id, UUID.randomUUID())
==>v[c2d673de-2425-4b42-bc1e-68ff20e3b0a8]
gremlin> g.V(UUID.fromString("c2d673de-2425-4b42-bc1e-68ff20e3b0a8"))
==>v[c2d673de-2425-4b42-bc1e-68ff20e3b0a8]

Related

Gremlin: how to overcome property null problem and write a query which updates all properties of a certain vertex?

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.

Cosmos DB Search Query which takes Vertex values with any character

I am using Azure cosmos Db, In cosmosDB i have so many vertexes, each vertex has properties in key value form. I want to find any gremlin query which checks Vertex values which start with any character.
Filter Query is there but for azure filter query is not supported, so is there any other Gremlin query which takes Vertex properties values which start with any character?
Although I never tried CosmosDB myself, I have to disagree with John. According to CosmosDB's docs, any range query on any property is processed from the index. Hence, if you want to find all person vertices that have a name property that starts with a, you can do:
g.V().has("person", "name", between("a", "b"))`
A concrete example over TinkerPop's toy graph:
gremlin> g = TinkerFactory.createModern().traversal()
==>graphtraversalsource[tinkergraph[vertices:6 edges:6], standard]
gremlin> g.V().has("name", between("m", "n")).valueMap()
==>[name:[marko], age:[29]]
gremlin> g.V().has("name", between("j", "k")).valueMap()
==>[name:[josh], age:[32]]
gremlin> g.V().has("name", between("j", "n")).valueMap()
==>[name:[marko], age:[29]]
==>[name:[lop], lang:[java]]
==>[name:[josh], age:[32]]
“start with any character” requires Full-Text search, yet Cosmos DB does not support it per their documentation https://learn.microsoft.com/en-us/azure/cosmos-db/gremlin-support#gremlin-steps .
JanusGraph support Full-Text search or String search, for example:
g.V().has('bookname', textPrefix('uni'))
For more info please refer to http://docs.janusgraph.org/latest/index-parameters.html#text-search

How to merge Two Vertex details and Edge Properties details Together in a single gremlin query

How to merge Two Vertex details and Edge Properties details Together in a single gremlin query.
I'm having two Vertices :
UserInfo vertex
PostInfo vertex
EdgeInfo Between them
With Gremlin Query : g.v(2569472).out('_label','WallPost')[0..1]
I'm getting UserPost Vertex details , i want to add UserVertex detail in the response (i.e gender ) and Edge property detail in the response (i.e EdgeMessage)
I'm trying to compare sql equivalent innerjoin operation with gremlin from sql2gremlin but i'm not able to get the desired result.
SQL2Gremlin is written for TinkerPop 3, you're still using TinkerPop 2 (which is a lot more complicated IMO). Anyway, here's how you would do it in TP2:
gremlin> g = TinkerGraphFactory.createTinkerGraph()
==>tinkergraph[vertices:6 edges:6]
gremlin> g.v(1).outE("knows")
==>e[7][1-knows->2]
==>e[8][1-knows->4]
gremlin> g.v(1).outE("knows").inV().retain([g.v(4)])
==>v[4]
gremlin> g.v(1).as("x").outE("knows").as("y").inV().retain([g.v(4)]).select(["x","y"]) {it.map()} {it.weight}
==>[x:{name=marko, age=29}, y:1.0]

Tinkerpop - how do I find a node in the graph?

I can't seem to find a specific node in the graph without traversing the whole thing. Is there something I'm missing?
I'm using tinkerpop blueprints.
Orientdb gives some sort of unsemantic id to a node such as '#8:1' - how do I find this without knowing the id? vertex has a property like 'user=jason' that will identify it.
I'm thinking I'll just use redis to store the user/location pair or otherwise use a supernode (no thanks)
Blueprints has the notion of key indices.
https://github.com/tinkerpop/blueprints/wiki/Graph-Indices
Given your example, define a key index for "user", then query it with the key index. Here's an example using OrientDB from a Gremlin prompt:
gremlin> g = new OrientGraph("memory://graph")
==>orientgraph[memory://graph]
gremlin> g.createKeyIndex("user", Vertex.class)
==>null
gremlin> g.addVertex([user:"Jason"])
==>v[#8:-3]
gremlin> g.addVertex([user:"Rick"])
==>v[#8:-4]
gremlin> g.stopTransaction(SUCCESS)
==>null
gremlin> g.V('user','Jason')
==>v[#8:1]

Key index on Bulbs / Gremlin / Titan

I'm trying to port my Neo4J application to Titan and I'm having some issues related to indexes.
I understand that Titan does not support vertex or edge indexes, only "key" indexes, is it right?
I'm also working with Bulbs models, for example:
class Person(Node):
element_type = 'person'
facebook_id = String(indexed=True)
It should be possible when adding Person(facebook_id='111') to retrieve using:
gremlin> g.getVertices('facebook_id', '111')
It doesn't work and tells me that I need to create the key index before using it. So I dropped the keyspace and manually created the index in rexster doghouse:
gremlin> g.createKeyIndex("facebook_id", Vertex.class);
After that, created Person(facebook_id='111') with Bulbs and tried to retrieve on rexster doghouse:
gremlin> g.getVertices("facebook_id", "111")
And got empty response. When fetching using Titan vertex ID it works, but "facebook_id" comes empty and ".map()" doesn't work:
gremlin> g.v(4)
==>v[4]
gremlin> g.v(4).name
==>Renato Garcia Pedigoni
gremlin> g.v(4).facebook_id # nothing returned!
gremlin> g.v(4).map()
==>javax.script.ScriptException: java.lang.IllegalArgumentException: The value is already used by another vertex and the key is unique
PS
It's the first vertex I created after dropping the keyspace
Is it possible create keys indexes automatically?
Any tips?
Thanks!
Renato Pedigoni
Yes, Titan only supports key indexes which replace the old manual vertex indexes with similar functionality but less overhead.
The exception indicates that the property is not only indexed but also unique (see Titan Types for more information).
Have you tried adding the vertex and key index in Gremlin (i.e. without Bulbs)?
Also, James has done a lot of work on Bulbs with respect to Titan integration, so this particular issue might be resolved in the most current version.

Resources