Adding Multiple Unique Vertices - gremlin

I want to write a single gremlin query that will create multiple vertices, but only does so if they are all unique. I know I can use the get or addV method by using coalesce step mentioned in the comments.
g.V().has('com.demo.test', '__type', 'Namespace').fold().coalesce(unfold(), addV('com.demo.test').property('__type', 'Namespace'))
This will hadd a single vertex only if it does not exist already. What if i want to do this same procedure for multiple edges and vertices all in a single query? My goal is that if one of the vertices/edges is not unique, none of them are created. However I understand that may not be possible so all answers are welcome.
Thanks

I found a possible solution. This works but there might be a better way to do it.
g.V().coalesce(
V().has(label,'Namespace61'),
addV('Namespace61')).
coalesce(
V().has(label,'Namespace76'),
addV('Namespace76')).
coalesce(
V().has(label,'Namespace74'),
addV('Namespace74')
).dedup()

Related

Tinkerpop Gremlin is it better to query with hasId or to search by property values

Using Tinkerpop Gremlin (Neptune DB), is there a preferred/"faster" way to query?
For example, let's say I have a graph containing the node:
label: Student
id: 'student/12345'
studentId: '12345'
name: 'Bob'
Is there a preferred query? (for this example let's say we know the field 'studentId' value, which is also part of the id)
g.V().filter('studentId', '12345')
vs
g.V().filter(hasId(TextP.containing('12345'))
or using "has"/"hasId" vs "filter"?
g.V().has('studentId', '12345')
vs
g.V().hasId(TextP.containing('12345'))
So there seems to be two questions here, one about filter() vs has() and the other about using the vertex id versus a property.
The answer to the first question is going to depend on the underlying database implementation and what is has/has not optimized. In general, and in Neptune, I would suggest using the g.V().has('studentId', '12345') pattern to filter on a property as it is optimized and easier to read.
The answer to the second question also depends on the database implementaiton, as not all allow for setting of the vertex ids. Other databases may vary but in Neptune setting ids is allowed and a direct lookup by ID is the fastest (e.g. g.V('12345') or g.V().hasId('12345')) way to look something up as it is a single index lookup. One thing to note is that in Neptune vertex/edge id values need to be globally unique so you need to ensure that you will only have one vertex or edge with a specific id.

How to get properties hasid/key with vertexes info in one gremlin query or Gremlin.Net

I try to get properties which has key or id in following query by Gremlin.Net, but vertex info(id and label) in VertexProperty is null in result.
g.V().Properties<VertexProperty>().HasKey(somekey).Promise(p => p.ToList())
So i try another way, but it's return class is Path, and i had to write an ugly code for type conversion.
g.V().Properties<VertexProperty>().HasKey(somekey).Path().By(__.ValueMap<object, object>(true))
Is there a better way to achieve this requirement
I think basically the only thing missing to get what you want is the Project() step.
In order to find all vertices that have a certain property key and then get their id, label, and then all information about that property, you can use this traversal:
g.V().
Has(someKey).
Project<object>("vertexId", "vertexLabel", "property").
By(T.Id).
By(T.Label).
By(__.Properties<object>(someKey).ElementMap<object>()).
Promise(t => t.ToList());
This returns a Dictionary where the keys are the arguments given to the Project step.
If you instead want to filter by a certain property id instead of a property key, then you can do it in a very similar way:
g.V().
Where(__.Properties<object>().HasId(propertyId)).
Project<object>("vertexId", "vertexLabel", "property").
By(T.Id).
By(T.Label).
By(__.Properties<object>(someKey).ElementMap<object>()).
Promise(t => t.ToList());
This filters in both cases first the vertices to only have vertices that have the properties we are looking for. That way, we can use the Project() step afterwards to get the desired data back.
ElementMap should give all information back about the properties that you want.
Note however that these traversals will most likely require a full graph scan in JanusGraph, meaning that it has to iterate over all vertices in your graph. The reason is that these traversals cannot use an index which would make them much more efficient. So, for larger graphs, the traversals will probably not be feasible.
If you had the vertex ids available instead of the property ids in the second traversal, then you could make the traversal a lot more efficient by replacing g.V().Where([...]) simply with g.V(id).

Simple outer-join like gremlin query not returning any results

I wrote the simple query below to traversal between Person to Country but it’s not returning any results.
g.V().hasLabel("Person").as("p").out("from").hasLabel("Country").as("c").select("p", "c")
In the actual data, only Person vertices exists and no Country vertices or from edges exist. I expected to at least return p - basically I want to do a left outer join. However, if I have Country and from data as well, the query returns results.
I tried another query using match as well but still no results unless there are actual data:
g.V().hasLabel("Person").has("name","bob").match(__.as("p").out("from").hasLabel("Country").as("c")).select("p", "c")
I'm running these queries against Datastax Enterpise Graph.
Any idea why it’s returning no results?
The result you are getting is expected. If there are no "from" edges then the traverser essentially dies and does not proceed any further. Perhaps you could consider using project():
g.V().hasLabel("Person").
project('name','country').
by('name')
by(out('from').hasLabel('Country').values('name').fold())
With the "modern" toy graph in TinkerPop, the output looks like this:
gremlin> g.V().hasLabel('person').project('name','knows').by().by(out('knows').values('name').fold())
==>[name:v[1],knows:[vadas,josh]]
==>[name:v[2],knows:[]]
==>[name:v[4],knows:[]]
==>[name:v[6],knows:[]]
In the future, when you submit questions about Gremlin, please include a Gremlin script that can be pasted into a Gremlin Console which makes it easier to try to more directly answer your specific question.

Querying titan graph for only indexed vertices without traversing complete graph

I am trying to retrieve only indexed vertices in the graph
I used the below query
Iterator<Vertex> vertices = titanTransaction.query().has("name").vertices().iterator();
This query traverses to the complete graph and fetches the result, Can anyone suggest me a better way, The name vertex is indexed.
Thanks
You should be able to use the .has(key,value) method https://github.com/thinkaurelius/titan/blob/0.5.4/titan-core/src/main/java/com/thinkaurelius/titan/graphdb/query/graph/GraphCentricQueryBuilder.java#L113
Iterator<Vertex> vertices = titanTransaction.query().has("name","john").vertices().iterator();
Should do the trick.
Have you tried:
graph.V('name','nameOfTargetVertex').next()
I think this should use your index on the attribute name, according to http://gremlindocs.com/#transform/v .

When is it appropriate to use g.query()...vertex() vs g.V.has()

I'm a little confused about this one. Several similar examples can be found throughout the documentation. Such as :
g.V.has('name','hercules').next()
g.query().has("name",EQUAL,"hercules").vertices()
Could someone clarify what the difference in the process is between the two above?
Thanks
The first is gremlin-groovy syntax:
g.V.has('name','hercules').next()
and either iterates all vertices looking for vertices that have a "name" property with a value of "hercules". In the event that "name" is indexed then titan will utilize the index to avoid the linear scan to find such vertices.
The second is basically Java and the Titan API. The above gremlin-groovy code basically compiles down to your second statement:
g.query().has("name",EQUAL,"hercules").vertices()
however, in the case of the second statement it returns an iterator of all vertices that match the filter and doesn't just pop off the first one as shown in the gremlin statement (given the use of next()).

Resources