Gremlin access a property "id" - groovy

We use OrientDB and when using the Gremlin terminal, we cannot query for a single user id.
We have this
gremlin> g.V('#class','PERSON')[0..<5].map();
==>{id=50269488}
==>{id=55225663}
==>{id=6845786}
==>{id=55226938}
==>{id=55226723}
gremlin> g.V('#class','PERSON').has('id',50269488)[0..<5].map();
gremlin>
As you can see I tried filtering for that first id, but it doesn't return anything. I even tried typecasting to 50269488L as suggested here
any tips what to try?

I guess it's because property id is reserved somehow.
An example:
gremlin> g.V.id
==>#15:0
==>#15:1
...
This returns the RecordId instead of the property id.
From studio, e.g.:
create class PERSON extends V
create Property PERSON.id2 long
create vertex PERSON set id2 = 12345
Then this should work:
gremlin> g.V('#class','PERSON').has('id2',12345L)[0..<5].map();
==>{id2=12345}
UPDATE:
A workaround to this problem is to filter with getProperty method:
g.V('#class','PERSON').filter{it.getProperty("id")==12345}[0..<5].map();

Related

How to get the response by passing an UUID as parameter in gremlin query?

I have a province id which is an UUID. I am able to get all the campaign sites without passing province id as a parameter.
gremlin> :> g.V().hasLabel('Province').has('code','IN').in('partOf').hasLabel('Province').has('type','state').in('partOf')..hasLabel('Province').has('type','city').in('partOf').hasLabel('Province').has('type','campaignSite').valueMap('provinceId')
==>{provinceId=[55bde744-307f-4767-8384-ed051bed414a]}
==>{provinceId=[1679cf43-f808-45b3-b132-244a03bc180b]}
==>{provinceId=[afe4ad5e-e911-4048-9364-63531657a5ee]}
==>{provinceId=[726dba5b-6d3c-45b1-8435-a726878e2304]}
==>{provinceId=[10721b98-a4e7-4672-9140-3b05c2c445d2]}
==>{provinceId=[fc61be4e-58ba-4874-b004-199a628bb1e3]}
==>{provinceId=[db43876d-267b-4063-bd51-e1ef47b77541]}
==>{provinceId=[49c68244-1ada-4131-b2dd-d8e0f6624379]}
==>{provinceId=[21bb9520-4d7d-4ffb-8458-abc1f79371ed]}
==>{provinceId=[cbcb774a-775b-42e3-92de-843bbf2141f6]}
==>{provinceId=[ed896879-3b94-491a-a759-680adcc22bbd]}
==>{provinceId=[cee46370-63b0-4cf3-898a-e38faef0edb9]}
==>{provinceId=[2850d6f1-a9fb-4e48-99d6-169c1b8570ca]}
==>{provinceId=[3c665c3a-4ddb-4909-a643-b24f27c2b71f]}
==>{provinceId=[4df1ceec-27f1-4f21-89cb-1d46b0332d21]}
==>{provinceId=[ef3094ea-390c-439d-8dfa-fdb1669fcaa2]}
==>{provinceId=[b00865c0-5482-48c4-86d5-34070a03dc12]}
==>{provinceId=[eb6eccd7-d842-4753-8b1e-3668a2cc9869]}
==>{provinceId=[184c1d55-eba0-41ac-9131-95ce5228c20d]}
==>{provinceId=[2c2c8a9e-f050-4921-a0c5-eba20e3bcc36]}
==>{provinceId=[83276863-b35b-4dde-8789-5aa90311a24b]}
==>{provinceId=[25623cb8-7564-4d8f-a276-ac40842209c7]}
==>{provinceId=[dcb9c708-8e23-4298-8369-0feb9e50c074]}
==>{provinceId=[06948da8-3cd3-4cd7-8d91-8aaa666e557d]}
But when I passed UUID as parameter to the query, then the result I got is nothing.
g.V().hasLabel('Province').has('code','IN').in('partOf').hasLabel('Province').has('type','state').inE('partOf').outV().hasLabel('Province').has('type','city').inE('partOf').outV().hasLabel('Province').has('type','campaignSite').has('provinceId','06948da8-3cd3-4cd7-8d91-8aaa666e557d').valueMap(true)
But when I passed name as a parameter, then I am getting the correct result.
gremlin> :> g.V().hasLabel('Province').has('code','IN').in('partOf').hasLabel('Province').has('type','state').inE('partOf').outV().hasLabel('Province').has('type','city').inE('partOf').outV().hasLabel('Province').has('type','campaignSite').has('name','City Center').valueMap(true)
==>{label=Province, id=696332448, name=[City Center], location[POINT(78.448889 17.415)], type=[campaignSite], provinceId=[2c2c8a9ef050-4921-a0c5-eba20e3bcc36]}
I don't know what is happening.
Is it possible that your problem is that you are storing your UUID as an actual UUID object but are querying by string:
has('provinceId','06948da8-3cd3-4cd7-8d91-8aaa666e557d')
If you store the "provinceId" as a UUID object then query it as such:
has('provinceId', UUID.fromString('06948da8-3cd3-4cd7-8d91-8aaa666e557d'))
I don't think JanusGraph does that type coercion for you in this case.

I am using JanusGraph 0.2 with Cassandra 3.9. How can I replace a vertex?

We can update a vertex for example:
g.V(vertex_id).property("name","Marko")
is there any way to replace a vertex?
So you want to replace all properties of one vertex by properties of another vertex (at least that's how I understand your question together with your comment).
To delete all properties you simply have to drop them:
g.V(vertex_id).properties().drop().iterate()
and we can see how to copy all properties from one vertex to another in this response by Daniel Kuppitz to a question on how to merge two vertices:
g.V(vertex_with_new_properties).
sideEffect(properties().group("p").by(key).by(value())).
cap("p").unfold().as("kv").
V(vertex_id).
property(select("kv").select(keys), select("kv").select(values)).
iterate()
When we combine those two traversals, then we get a traversal that drops the old properties and copies over the new properties from the other vertex:
g.V(vertex_id).
sideEffect(properties().drop()).
V(vertex_with_new_properties).
sideEffect(properties().group("p").by(key).by(value())).
cap("p").unfold().as("kv").
V(vertex_id).
property(select("kv").select(keys), select("kv").select(values)).
iterate()
In action for the modern graph:
// properties before for both vertices:
gremlin> g.V(1).valueMap(true)
==>{id=1, label=person, name=[marko], age=[29]}
gremlin> g.V(2).valueMap(true)
==>{id=2, label=person, name=[vadas], age=[27]}
// Replace all properties of v[1]:
gremlin> g.V(1).
sideEffect(properties().drop()).
V(2).
sideEffect(properties().group("p").by(key).by(value())).
cap("p").unfold().as("kv").
V(1).
property(select("kv").select(keys), select("kv").select(values)).
iterate()
// v[1] properties after:
gremlin> g.V(1).valueMap(true)
==>{id=1, label=person, name=[vadas], age=[27]}

Output vertice and adjacent vertices in same query with tinkerpop3

I'm new to gremlin and trying to find out how to get an article along with the author and attachments in the same result using Azure Cosmos DB with GraphSON.
My graph looks like this:
[User] <- (edge: author) - [Article] - (edge: attachments) -> [File1, File2]
I would like to fetch everything I need in the UI to show an article along with author and info about attachments in on request.
What I'm trying to fetch is something similar to this pseudo-code:
{
article: {...},
author: [{author1}],
attachment: [{file1}, {file2}]
}
My attempt so far:
g.V().hasLabel('article').as('article').out('author', 'attachments').as('author','attachments').select('article', 'author', 'attachments')
How can I write the query to get the distinct values?
When asking questions about Gremlin it is always helpful to provide some sample data in a form like this:
g.addV('user').property('name','jim').as('jim').
addV('user').property('name','alice').as('alice').
addV('user').property('name','bill').as('bill').
addV('article').property('title','Gremlin for Beginners').as('article').
addV('file').property('file','/files/a.png').as('a').
addV('file').property('file','/files/b.png').as('b').
addE('authoredBy').from('article').to('jim').
addE('authoredBy').from('article').to('alice').
addE('authoredBy').from('article').to('bill').
addE('attaches').from('article').to('a').
addE('attaches').from('article').to('b').iterate()
Note that I modified your edge label names to be more verb-like so that they distinguish themselves better from the noun-like vertex labels. It tends to read nicely with the direction of the edge, as in: article --authoredBy-> user
Anyway, your problem is most easily solved with the project() step:
gremlin> g.V().has('article','title','Gremlin for Beginners').
......1> project('article','authors','attachments').
......2> by().
......3> by(out('authoredBy').fold()).
......4> by(out('attaches').fold())
==>[article:v[6],authors:[v[0],v[2],v[4]],attachments:[v[10],v[8]]]
In the above code, note the use of fold() within the by() steps - that will force the full iteration of the inner traversal and get it into a list. If you miss that step you will get just one result (i.e. the first).
Going one step further, I added valueMap() and next'd the result so that you could better see the properties contained in the vertices above.
gremlin> g.V().has('article','title','Gremlin for Beginners').
......1> project('article','authors','attachments').
......2> by(valueMap()).
......3> by(out('authoredBy').valueMap().fold()).
......4> by(out('attaches').valueMap().fold()).next()
==>article={title=[Gremlin for Beginners]}
==>authors=[{name=[jim]}, {name=[alice]}, {name=[bill]}]
==>attachments=[{file=[/files/b.png]}, {file=[/files/a.png]}]

How do you add elements to a set with DataStax QueryBuilder?

I have a table whose column types are
text, bigint, set<text>
I'm trying to update a single row and add an element to the set using QueryBuilder.
The code that overwrites the existing set looks like this (note this is scala):
val query = QueryBuilder.update("twitter", "tweets")
.`with`(QueryBuilder.set("sinceid", update.sinceID))
.and(QueryBuilder.set("tweets", setAsJavaSet(update.tweets)))
.where(QueryBuilder.eq("handle", update.handle))
I was able to find the actual CQL for adding an element to a set which is:
UPDATE users
SET emails = emails + {'fb#friendsofmordor.org'} WHERE user_id = 'frodo';
But could not find an example using QueryBuilder.
Based off of the CQL I also tried:
.and(QueryBuilder.set("tweets", "tweets"+{setAsJavaSet(update.tweets)}))
But it did not work. Thanks in advance
Use add (add one element at a time) or addAll (more than one any number of element at a time) method to add to a set.
To extend Ananth's answer:
QueryBuilder.add does not support BindMarker. To use BindMarker while adding in set, it is required to use QueryBuilder.addAll only.*
*Just a note, Collections.singleton may come in handy in this regard.
Using #Ananth and #sazzad answers, the code below works:
Session cassandraSession;
UUID uuid;
Long value;
Statement queryAddToSet = QueryBuilder
.update("tableName")
.with(QueryBuilder.addAll("setFieldName", QueryBuilder.bindMarker()))
.where(QueryBuilder.eq("whereFieldName", QueryBuilder.bindMarker()));
PreparedStatement preparedQuery = cassandraSession.prepare(queryAddToSet);
BoundStatement boundQuery = preparedQuery.bind();
boundQuery
.setUUID("whereFieldName", uuid)
.setSet("setFieldName", Collections.singleton(value));
session.execute(boundQuery);

Retrieving Properties from DbSqlQuery

Background: Project is a Data Import utility for importing data from tsv files into a EF5 DB through DbContext.
Problem: I need to do a lookup for ForeignKeys while doing the import. I have a way to do that but the retrieval if the ID is not functioning.
So I have a TSV file example will be
Code Name MyFKTableId
codevalue namevalue select * from MyFKTable where Code = 'SE'
So when I process the file and Find a '...Id' column I know I need to do a lookup to find the FK The '...' is always the entity type so this is super simple. The problem I have is that I don't have access to the properties of the results of foundEntity
string childEntity = column.Substring(0, column.Length - 2);
DbEntityEntry recordType = myContext.Entry(childEntity.GetEntityOfReflectedType());
DbSqlQuery foundEntity = myContext.Set(recordType.Entity.GetType()).SqlQuery(dr[column])
Any suggestion would be appreciated. I need to keep this generic so we can't use known type casting. The Id Property accessible from IBaseEntity so I can cast that, but all other entity types must be not be fixed
Note: The SQL in the MyFKTableId value is not a requirement. If there is a better option allowing to get away from SqlQuery() I would be open to suggestions.
SOLVED:
Ok What I did was create a Class called IdClass that only has a Guid Property for Id. Modified my sql to only return the Id. Then implemented the SqlQuery(sql) call on the Database rather than the Set([Type]).SqlQuery(sql) like so.
IdClass x = ImportFactory.AuthoringContext.Database.SqlQuery<IdClass>(sql).FirstOrDefault();
SOLVED:
Ok What I did was create a Class called IdClass that only has a Guid Property for Id. Modified my sql to only return the Id. Then implemented the SqlQuery(sql) call on the Database rather than the Set([Type]).SqlQuery(sql) like so.
IdClass x = ImportFactory.AuthoringContext.Database.SqlQuery<IdClass>(sql).FirstOrDefault();

Resources