the result of .hasLabel("xxx") and .label() is not matching - gremlin

The JanusGraph version is 0.5.3
storage.backend=hbase
I do this query,I get the correct label
gremlin> g.V().has("eventid","3bbe").label()
==>Company
but I do the follow query,I get result nothing
gremlin> g.V().has("eventid","3bbe").hasLabel("Company")
gremlin>
but use other eventid, i can get correct result
gremlin> g.V().has("eventid","4bbe").label()
==>Company
gremlin> g.V().has("eventid","4bbe").hasLabel("Company")
==>v[1714175422812422000]

I agree with Kelvin and Binary suggestion stated in comments. You should check the "Company" string once in "g.V().has("eventid","3bbe")" vertex properties. You can check the same using following query,
g.V().has("eventid","3bbe").valueMap(true)
This will gives you "label" as property in the output value map.
Also, if then to you find that the String "Company" is same in both the query. Then there may be an issue in Indexing done on "eventid". (Assuming that some kind of index is created on this, as this can leads to this problem).
To solve this you can try reindexing. Steps are given as follows,
For Reindex:
mgmt = graph.openManagement()
i = mgmt.getGraphIndex('IndexName')
mgmt.updateIndex(i, SchemaAction.REINDEX)
mgmt.commit()
For Enable the index:
ManagementSystem.awaitGraphIndexStatus(graph, 'IndexName').status(SchemaStatus.ENABLED).call()
NOTE: if you get "false" in enabling the index, Try enabling it 2 3 times using the same command (ManagementSystem.awaitGraphIndexStatus(graph, 'IndexName').status(SchemaStatus.ENABLED).call()). It would work eventually.

Related

I am facing issues with group() in gremlin

I am trying to find the count of all workspaces group by Customer, and then sorting the response with the count value.
t3 = g.withSideEffect("Neptune#repeatMode","BFS")
.V().has("Project","sid","A68FA527BB214F0E9D2287B455BEFE0A8AACFED0724B407F9EBF727ED439E8ED")
.both().hasLabel("Customer").group().by().by(
both().hasLabel("Workspace").count().order().by(Column.values,Order.desc)
)
.unfold()
.project("rowName","data")
.by(select(Column.keys).properties(MandatoryCustomerAttributes.firstName.name()).value())
.by(select(Column.values))
.by(fold().unfold());
I am facing the following error which I am not able to understand. If someone can help it will be great.
java.util.concurrent.CompletionException: org.apache.tinkerpop.gremlin.driver.exception.ResponseException: {"requestId":"c3246ac6-d306-41e6-a6d1-3adbacb928fb","code":"InvalidParameterException","detailedMessage":"The provided object does not have accessible keys: class java.lang.Long"}
at java.util.concurrent.CompletableFuture.reportJoin(CompletableFuture.java:375)
at java.util.concurrent.CompletableFuture.join(CompletableFuture.java:1934)
at org.apache.tinkerpop.gremlin.driver.ResultSet.one(ResultSet.java:123)
at org.apache.tinkerpop.gremlin.driver.ResultSet$1.hasNext(ResultSet.java:175)
at org.apache.tinkerpop.gremlin.driver.ResultSet$1.next(ResultSet.java:182)
at org.apache.tinkerpop.gremlin.driver.ResultSet$1.next(ResultSet.java:169)
at org.apache.tinkerpop.gremlin.driver.remote.DriverRemoteTraversal$TraverserIterator.next(DriverRemoteTraversal.java:146)
at org.apache.tinkerpop.gremlin.driver.remote.DriverRemoteTraversal$TraverserIterator.next(DriverRemoteTraversal.java:131)
at org.apache.tinkerpop.gremlin.driver.remote.DriverRemoteTraversal.nextTraverser(DriverRemoteTraversal.java:112)
at org.apache.tinkerpop.gremlin.process.remote.traversal.step.map.RemoteStep.processNextStart(RemoteStep.java:80)
at org.apache.tinkerpop.gremlin.process.traversal.step.util.AbstractStep.next(AbstractStep.java:129)
at org.apache.tinkerpop.gremlin.process.traversal.step.util.AbstractStep.next(AbstractStep.java:39)
at org.apache.tinkerpop.gremlin.process.traversal.util.DefaultTraversal.next(DefaultTraversal.java:204)
at org.apache.tinkerpop.gremlin.process.traversal.Traversal.forEachRemaining(Traversal.java:278)
at com.callcomm.eserve.enitty.trial.NeptuneTrialCode.main(NeptuneTrialCode.java:373)
Ok I think after staring at this for a while I spotted the issue.
This part of the query
hasLabel("Workspace").count().order().by(Column.values,Order.desc
Is going to try to apply Column.values against the count result (an integer, not a map) - hence the error message.
You will need to order the group after it is created. Here is a simple example, note the use of local.
g.V('44','3','8').
group().
by().
by(out().count()).
order(local).
by(values,desc)
==>[v[8]:251,v[3]:93,v[44]:4]
As a side note, I did notice that the project only has only 2 items declared but has 3 by modulators. That should not be a problem but you may not be getting the results you wanted.

Gremlin : Checking existence in traversal step or set

Background:
I am trying to run a search through a graph and change the search behavior based on if the discovered node belongs to a pre-defined set available before the query is executed.
I can't find any documentation on how to cross-check if a vertex or attribute is present in a set in gremlin.
Examples:
Given: g.V('id1', 'id2', 'id3').as('a')
Find: if a includes 'id4'
OR
Given: g.V('id1', 'id2', 'id3').fold().store('a') => ['id1', 'id2', 'id3']
Find: if a contains id4
One way to approach this is to use the coalesce step. Here is a simple example from the Gremlin Console.
gremlin> g.V(1,2,3).fold().as('found').V(3).coalesce(where(within('found')).constant('found'),constant('not found'))
==>found
gremlin> g.V(1,2,3).fold().as('found').V(4).coalesce(where(within('found')).constant('found'),constant('not found'))
==>not found

Get all edges between multiple vertices - JanusGraph

I am trying to write a gremlin query to get all the edges between a list of vertices.
Data redacted to protect privacy. User A(42651832) -reports_to-> User
B(28729440) -reports_to-> User C(19546208)
ids = [19546208, 28729440, 42651832]
I need to find all the edges between an arbitrary list of vertices
Seems simple, but I am unable to write a query that gives results I need.
gremlin> g.V(42651832).outE('reports_to').otherV().id()
==>28729440
gremlin> g.V(28729440).outE('reports_to').otherV().id()
==>19546208
gremlin> ids = [19546208, 28729440, 42651832]
==>19546208
==>28729440
==>42651832
gremlin> g.V(ids)
==>v[19546208]
==>v[28729440]
==>v[42651832]
gremlin> g.V(ids).bothE().where(otherV().hasId(ids))
gremlin> g.V(ids).bothE().where(otherV().hasId(within(ids)))
gremlin> g.V(ids).bothE().where(otherV().hasId(within(19546208, 28729440, 42651832)))
Apparently, I think there is a type conversion issue between gremlin console and JanusGraph.
quoting as string or converting to Long seems to work.
gremlin> g.V(ids).bothE().where(otherV().hasId(within("19546208", "28729440", "42651832")))
==>e[10r7d8-h3rs0-i6t-bmxy8][28729440-reports_to->19546208]
==>e[10r7d8-h3rs0-i6t-bmxy8][28729440-reports_to->19546208]
==>e[128qvr-pe6d4-i6t-h3rs0][42651832-reports_to->28729440]
==>e[128qvr-pe6d4-i6t-h3rs0][42651832-reports_to->28729440]
gremlin> g.V(ids).bothE().where(otherV().hasId(within(19546208L, 28729440L, 42651832L)))
==>e[10r7d8-h3rs0-i6t-bmxy8][28729440-reports_to->19546208]
==>e[10r7d8-h3rs0-i6t-bmxy8][28729440-reports_to->19546208]
==>e[128qvr-pe6d4-i6t-h3rs0][42651832-reports_to->28729440]
==>e[128qvr-pe6d4-i6t-h3rs0][42651832-reports_to->28729440]
gremlin>
gremlin> g.V(ids).bothE().where(otherV().hasId(within(19546208L, 28729440L, 42651832L))).dedup()
==>e[10r7d8-h3rs0-i6t-bmxy8][28729440-reports_to->19546208]
==>e[128qvr-pe6d4-i6t-h3rs0][42651832-reports_to->28729440]
Any other suggestions. Not sure why JanusGraph works this way.
This isn't quite a full answer, but hopefully it gets you close enough. I used GraphOfTheGods to test it out.
This will get all the paths from the ids list to the quoted ids in hasID() and then output a list of all the edges traversed in each path. I added a limit for readability. You could easily add all the values to a set to get a deduped answer.
# Save all the graph of the gods vertex ids to a variable
ids = [4112,4128,4136,8232,12328,16424,20520,4296,4328,4344,8440,12536]
paths = g.V(ids).until(hasId("8440","12536")).repeat(bothE().aggregate("e").otherV().simplePath()).limit(3).select('e')
==>[e[74v-6ig-9hx-368][8440-battled->4112]]
==>[e[74v-6ig-9hx-368][8440-battled->4112],e[7xb-6ig-9hx-36o][8440-battled->4128],e[1l0-36o-b2t-9o8][4128-lives->12536],e[9vp-co8-bv9-36o][16424-pet->4128]]
==>[e[74v-6ig-9hx-368][8440-battled->4112],e[7xb-6ig-9hx-36o][8440-battled->4128],e[1l0-36o-b2t-9o8][4128-lives->12536],e[9vp-co8-bv9-36o][16424-pet->4128]]
What I was able to originally get was a full path with connecting vertexes which I am including in case it could potentially be helpful.
paths = g.V(ids).until(hasId("8440","12536")).repeat(bothE().otherV().simplePath()).path().limit(5)
==>[v[4112],e[74v-6ig-9hx-368][8440-battled->4112],v[8440]]
==>[v[4128],e[7xb-6ig-9hx-36o][8440-battled->4128],v[8440]]
==>[v[4128],e[1l0-36o-b2t-9o8][4128-lives->12536],v[12536]]
==>[v[4128],e[9vp-co8-bv9-36o][16424-pet->4128],v[16424],e[9hh-co8-b2t-9o8][16424-lives->12536],v[12536]]
==>[v[4128],e[9vp-co8-bv9-36o][16424-pet->4128],v[16424],e[8p1-co8-cnp-3co][16424-brother->4344],v[4344],e[6cf-6ig-7x1-3co][8440-father->4344],v[8440]]
Separately I did some checking with the GraphOfTheGods and the explain() step and it definitely seems like a bug. If I set a list to variable it is performing an equal step instead of a within step.
paths = g.V(ids).until(hasId(ids)).repeat(out().simplePath()).limit(10).path().explain()
...RepeatStep(until([HasStep([~id.eq([4112, 4128, ...])])]),
where as listing in quotes it will properly do a within check.
paths = g.V(ids).until(hasId("8440","12536")).repeat(outE().simplePath()).limit(10).path().explain()
...RepeatStep(until([HasStep([~id.within([8440, 12536])])])

Query regarding the functionality of repeat().until()

Data: Tinkerpop Modern sample graph
Query:
gremlin> g.V(1).repeat(both()).until(hasLabel("person")).path().by("name")
==>[marko,vadas]
==>[marko,josh]
==>[marko,lop,marko]
==>[marko,lop,josh]
==>[marko,lop,peter]
What doc says:
...If until() comes after repeat() it is do/while looping. If until()
comes before repeat() it is while/do looping...
Doubt:
Shouldn't until terminate the query after first match marko-vadas? or am I missing something?
It terminates the traverser on this path, otherwise you would get [marko,vadas,marko] next. The other paths were found by other traversers. If you only care about the first path, add a .limit(1).
gremlin> g.V(1).repeat(both()).until(hasLabel("person")).limit(1).path().by("name")
==>[marko,vadas]

Printing/Fetching Vertex values from a path

Just getting started with gremlin.
Printing out all the Vertex values worked out fine
gremlin> g.V().values()
==>testing 2
==>Cash Processing
==>Sales
==>Marketing
==>Accounting
I was able to find all the directly connected path between my Vertices.
gremlin> g.V().hasLabel('Process')
.repeat(both().simplePath())
.until(hasLabel('Process'))
.dedup().path()
==>[v[25],v[28]]
==>[v[25],v[26]]
==>[v[26],v[27]]
==>[v[26],v[25]]
Now am trying to print out the values in the path like ['Sales', 'Accounting'] instead of [v[25],v[28]]
Not been able to figure out a way yet
Already tried and failed with
Unfold: Does not get me 1-1 mapping
gremlin> g.V().hasLabel('Process').repeat(both().simplePath()).until(hasLabel('Process')).dedup().path().unfold().values()
==>Cash Processing
==>Accounting
==>Cash Processing
==>Sales
==>Sales
==>Marketing
==>Sales
==>Cash Processing
Path seems to be of a different data-type and does not support .values() function
gremlin> g.V().hasLabel('Process')
.repeat(both().simplePath())
.until(hasLabel('Process'))
.dedup().path().values()
org.apache.tinkerpop.gremlin.process.traversal.step.util.ImmutablePath cannot be cast to org.apache.tinkerpop.gremlin.structure.Element
Tried the following google searches and didnt get the answer
gremlin print a path
gremlin get values in a path
and few more word twisting
Found one at here that was for java but that didnt work for me
l = []; g.V().....path().fill(l)
(but cant create list, Cannot set readonly property: list for class: org.apache.tinkerpop.gremlin.structure.VertexProperty$Cardinality
)
I have running it on Gremlin console (running ./gremlin.sh)
You can use the by step to modulate the elements inside the path. For example by supplying valueMap(true) to by you get the properties of the vertices, together with the vertex labels and their ids:
gremlin> g.V().repeat(both().simplePath()).times(1).dedup().path().by(valueMap(true))
==>[[id:1,name:[marko],label:person,age:[29]],[id:3,name:[lop],lang:[java],label:software]]
==>[[id:1,name:[marko],label:person,age:[29]],[id:2,name:[vadas],label:person,age:[27]]]
==>[[id:1,name:[marko],label:person,age:[29]],[id:4,name:[josh],label:person,age:[32]]]
==>[[id:2,name:[vadas],label:person,age:[27]],[id:1,name:[marko],label:person,age:[29]]]
==>[[id:3,name:[lop],lang:[java],label:software],[id:6,name:[peter],label:person,age:[35]]]
==>[[id:4,name:[josh],label:person,age:[32]],[id:5,name:[ripple],lang:[java],label:software]]
I used the modern graph which is one of TinkerPop's toy graphs that are often used for such examples. Your output will look a bit different and you may want to use something else than valueMap(true) for the by modulator. The TinkerPop documentation of the path step itself contains two more advanced examples for path().by() that you might want to check out.

Resources