Expecting java.lang.ArrayList/java.lang.List instead of java.lang.String. Where am I going wrong?

gremlin> :remote connect tinkerpop.server conf/remote.yaml session
Jun 19, 2024 6:04:36 PM org.yaml.snakeyaml.internal.Logger warn
WARNING: Failed to find field for org.apache.tinkerpop.gremlin.driver.Settings.serializers
18:04:37 INFO org.apache.tinkerpop.gremlin.driver.Connection.<init> - Created new connection for ws://localhost:8182/gremlin
18:04:37 INFO org.apache.tinkerpop.gremlin.driver.ConnectionPool.<init> - Opening connection pool on Host{address=localhost/127.0.0.1:8182, hostUri=ws://localhost:8182/gremlin} with core size of 1
==>Configured localhost/127.0.0.1:8182-[f353f6b1-f0b6-4b21-b928-1fd772211169]
gremlin> :remote console
==>All scripts will now be sent to Gremlin Server - [localhost/127.0.0.1:8182]-[f353f6b1-f0b6-4b21-b928-1fd772211169] - type ':remote console' to return to local mode
gremlin> g = graph.traversal()
==>graphtraversalsource[standardjanusgraph[inmemory:[127.0.0.1]], standard]
gremlin>
gremlin> mgmt = graph.openManagement()
==>org.janusgraph.graphdb.database.management.ManagementSystem@1f373aaf
gremlin> maker = mgmt.makePropertyKey('language')
==>org.janusgraph.graphdb.types.StandardPropertyKeyMaker@40921f9d
gremlin> maker.dataType(String.class)
==>org.janusgraph.graphdb.types.StandardPropertyKeyMaker@40921f9d
gremlin> maker.cardinality(LIST)
==>org.janusgraph.graphdb.types.StandardPropertyKeyMaker@40921f9d
gremlin> maker.make()
==>language
gremlin> mgmt.commit()
==>null
gremlin> g.addV('domain').property('language', ['English', 'Hindi']).property('name', 'aim').next()
==>v[4104]
gremlin> g.V(4104).properties('language').value().next().getClass()
==>class java.lang.String
gremlin> :remote connect tinkerpop.server conf/remote.yaml session
Jun 19, 2024 6:04:36 PM org.yaml.snakeyaml.internal.Logger warn
WARNING: Failed to find field for org.apache.tinkerpop.gremlin.driver.Settings.serializers
18:04:37 INFO org.apache.tinkerpop.gremlin.driver.Connection.<init> - Created new connection for ws://localhost:8182/gremlin
18:04:37 INFO org.apache.tinkerpop.gremlin.driver.ConnectionPool.<init> - Opening connection pool on Host{address=localhost/127.0.0.1:8182, hostUri=ws://localhost:8182/gremlin} with core size of 1
==>Configured localhost/127.0.0.1:8182-[f353f6b1-f0b6-4b21-b928-1fd772211169]
gremlin> :remote console
==>All scripts will now be sent to Gremlin Server - [localhost/127.0.0.1:8182]-[f353f6b1-f0b6-4b21-b928-1fd772211169] - type ':remote console' to return to local mode
gremlin> g = graph.traversal()
==>graphtraversalsource[standardjanusgraph[inmemory:[127.0.0.1]], standard]
gremlin>
gremlin> mgmt = graph.openManagement()
==>org.janusgraph.graphdb.database.management.ManagementSystem@1f373aaf
gremlin> maker = mgmt.makePropertyKey('language')
==>org.janusgraph.graphdb.types.StandardPropertyKeyMaker@40921f9d
gremlin> maker.dataType(String.class)
==>org.janusgraph.graphdb.types.StandardPropertyKeyMaker@40921f9d
gremlin> maker.cardinality(LIST)
==>org.janusgraph.graphdb.types.StandardPropertyKeyMaker@40921f9d
gremlin> maker.make()
==>language
gremlin> mgmt.commit()
==>null
gremlin> g.addV('domain').property('language', ['English', 'Hindi']).property('name', 'aim').next()
==>v[4104]
gremlin> g.V(4104).properties('language').value().next().getClass()
==>class java.lang.String
Solution:
A few things you should know based on your needs: 1. with JanusGraph you can't store Map or List so that may be a blocker for you 2. multi-properties aren't List - they are multiple values stored under the same property key, so those semantics may be a blocker for you 3. Gremlin has no steps that can help you detect a type. Whatever type detection you would do, it would have to happen in the client application (technically what you are doing when you call next() and class) which may be a blocker for you. 4. Using just Gremlin It's hard to detect if you are using multiproperties or not because it has no knowledge of the schema. Maybe you could consult JanusGraph for the schema for the types. Counting properties of a key doesn't really work either because you could have a key with just one property and it still could be a multiproperty (with just one value)....
Jump to solution
18 Replies
triggan
triggan5mo ago
Might be next() causing the issue there... what do you get if you use toList() instead? or next(n) would return n results in a list.
Aiman
Aiman5mo ago
Can't use toList() because even if the property value is a String it is going to convert it to ArrayList
g.addV('domain').property('language', ['English', 'Hindi']).property('name', 'aim').next()
==>v[4104]
gremlin> g.V(4104).properties('language').value().toList().getClass()
==>class java.util.ArrayList
gremlin> g.V(4104).properties('name').value().toList().getClass()
==>class java.util.ArrayList
g.addV('domain').property('language', ['English', 'Hindi']).property('name', 'aim').next()
==>v[4104]
gremlin> g.V(4104).properties('language').value().toList().getClass()
==>class java.util.ArrayList
gremlin> g.V(4104).properties('name').value().toList().getClass()
==>class java.util.ArrayList
And this is the error if I use next(n)
gremlin> g.V(4104).properties('name').value().next(n).getClass()
No such property: n for class: Script17
Type ':help' or ':h' for help.
Display stack trace? [yN]y
groovy.lang.MissingPropertyException: No such property: n for class: Script17
gremlin> g.V(4104).properties('name').value().next(n).getClass()
No such property: n for class: Script17
Type ':help' or ':h' for help.
Display stack trace? [yN]y
groovy.lang.MissingPropertyException: No such property: n for class: Script17
triggan
triggan5mo ago
n would be a number. As in, n=3 to return 3 of the next results in a list.
Aiman
Aiman5mo ago
gremlin> g.V(4104).properties('name').value().next(3).getClass()
==>class java.util.ArrayList
gremlin> g.V(4104).properties('name').value().next(3).getClass()
==>class java.util.ArrayList
triggan
triggan5mo ago
I don't quite understand what your desired outcome is here. Do you want the result returned as a list or as a string? Or as a "stringified" list?
Aiman
Aiman5mo ago
I want it to return its respective Data Type . In the query I've added a List to a property language and a String to a property name. My expectations are if its language it should return ArrayList and if its name it should return String g.addV('domain').property('language', ['English', 'Hindi']).property('name', 'aim').next()
triggan
triggan5mo ago
Perhaps this is some oddity with Janusgraph, then. As TinkerGraph in Gremlin Console does just as you would expect:
gremlin> res = g.V(0L).properties('language').value().next()
==>English
==>Hindi
gremlin> res.getClass()
==>class java.util.ArrayList
gremlin> res = g.V(0L).properties('name').value().next()
==>aim
gremlin> res.getClass()
==>class java.lang.String
gremlin>
gremlin> res = g.V(0L).properties('language').value().next()
==>English
==>Hindi
gremlin> res.getClass()
==>class java.util.ArrayList
gremlin> res = g.V(0L).properties('name').value().next()
==>aim
gremlin> res.getClass()
==>class java.lang.String
gremlin>
Aiman
Aiman5mo ago
gremlin> res = g.V(4104).properties('language').value().next()
==>[English, Hindi]
gremlin> res.getClass()
==>class java.lang.String
gremlin> res = g.V(4104).properties('language').value().next()
==>[English, Hindi]
gremlin> res.getClass()
==>class java.lang.String
What was your create query? g.addV('domain').property('language', ['English', 'Hindi']).property('name', 'aim').next() This is the query i used
triggan
triggan5mo ago
g.addV('domain').property('language', ['English', 'Hindi']).property('name', 'aim')
g.addV('domain').property('language', ['English', 'Hindi']).property('name', 'aim')
Aiman
Aiman5mo ago
I'm confused. I've done the same thing
gremlin> g.addV('domain').property('language', ['English', 'Hindi']).property('name', 'aim')
==>v[8200]
gremlin> res = g.V(8200).properties('language').value().next()
==>[English, Hindi]
gremlin> res.getClass()
==>class java.lang.String
gremlin> g.addV('domain').property('language', ['English', 'Hindi']).property('name', 'aim')
==>v[8200]
gremlin> res = g.V(8200).properties('language').value().next()
==>[English, Hindi]
gremlin> res.getClass()
==>class java.lang.String
I've restarted the JanusGraph Server and followed the below steps
✦ ❯ bin/gremlin.sh
gremlin> :remote connect tinkerpop.server conf/remote.yaml session
Jun 19, 2024 7:36:10 PM org.yaml.snakeyaml.internal.Logger warn
WARNING: Failed to find field for org.apache.tinkerpop.gremlin.driver.Settings.serializers
19:36:11 INFO org.apache.tinkerpop.gremlin.driver.Connection.<init> - Created new connection for ws://localhost:8182/gremlin
19:36:11 INFO org.apache.tinkerpop.gremlin.driver.ConnectionPool.<init> - Opening connection pool on Host{address=localhost/127.0.0.1:8182, hostUri=ws://localhost:8182/gremlin} with core size of 1
==>Configured localhost/127.0.0.1:8182-[c215817f-7de5-4c70-bdfc-6549b5f5b7bb]
gremlin> :remote console
==>All scripts will now be sent to Gremlin Server - [localhost/127.0.0.1:8182]-[c215817f-7de5-4c70-bdfc-6549b5f5b7bb] - type ':remote console' to return to local mode
gremlin> g = graph.traversal()
==>graphtraversalsource[standardjanusgraph[inmemory:[127.0.0.1]], standard]
gremlin> g.addV('domain').property('language', ['English', 'Hindi']).property('name', 'aim')
Property value [[English, Hindi]] is of type class java.util.ArrayList is not supported
Type ':help' or ':h' for help.
Display stack trace? [yN]
✦ ❯ bin/gremlin.sh
gremlin> :remote connect tinkerpop.server conf/remote.yaml session
Jun 19, 2024 7:36:10 PM org.yaml.snakeyaml.internal.Logger warn
WARNING: Failed to find field for org.apache.tinkerpop.gremlin.driver.Settings.serializers
19:36:11 INFO org.apache.tinkerpop.gremlin.driver.Connection.<init> - Created new connection for ws://localhost:8182/gremlin
19:36:11 INFO org.apache.tinkerpop.gremlin.driver.ConnectionPool.<init> - Opening connection pool on Host{address=localhost/127.0.0.1:8182, hostUri=ws://localhost:8182/gremlin} with core size of 1
==>Configured localhost/127.0.0.1:8182-[c215817f-7de5-4c70-bdfc-6549b5f5b7bb]
gremlin> :remote console
==>All scripts will now be sent to Gremlin Server - [localhost/127.0.0.1:8182]-[c215817f-7de5-4c70-bdfc-6549b5f5b7bb] - type ':remote console' to return to local mode
gremlin> g = graph.traversal()
==>graphtraversalsource[standardjanusgraph[inmemory:[127.0.0.1]], standard]
gremlin> g.addV('domain').property('language', ['English', 'Hindi']).property('name', 'aim')
Property value [[English, Hindi]] is of type class java.util.ArrayList is not supported
Type ':help' or ':h' for help.
Display stack trace? [yN]
@triggan What are the prerequisites to be followed before executing the query?
spmallette
spmallette5mo ago
you can't store List in JanusGraph i don't think. it's not a supported type: https://docs.janusgraph.org/v0.3/basics/schema/#property-key-data-type if you set Cardinality.LIST then it looks like JansuGraph will coerce a List to multiproperties which is why value() returns a string (i.e. the first multiproperty) ```gremlin> g = TinkerFactory.createTheCrew().traversal() ==>graphtraversalsource[tinkergraph[vertices:6 edges:14], standard] gremlin> g.V(1).valueMap() ==>[name:[marko],location:[san diego,santa cruz,brussels,santa fe]] gremlin> g.V(1).properties('location').value().next() ==>san diego gremlin> g.V(1).properties('location').value() ==>san diego ==>santa cruz ==>brussels ==>santa fe gremlin> g.V(1).map(properties('location').value().fold()) ==>[san diego,santa cruz,brussels,santa fe] ``` so, if you want them as a List you could fold()` them up as shown in that last traversal
Aiman
Aiman5mo ago
How was location created ? Since I'm getting an error while creating
spmallette
spmallette5mo ago
you just call property() with the same key for each "location" yout want to add:"
property(list,'k','v1').property(list,'k','v2')...
property(list,'k','v1').property(list,'k','v2')...
or, again, it looked like when you set the schema to use LIST cardinality it coerced the list automatically for you to multiproperties....... https://docs.janusgraph.org/schema/advschema/#multi-properties
Aiman
Aiman5mo ago
I've restarted the janusgraph server and ran these
gremlin> g.addV('domain').property(list,'language', 'English').property(list,'language', 'Kannada') .property(list,'language', 'Hindi').next()
==>v[4304]
gremlin> res = g.V(4304).properties('language').value().next()
==>English
gremlin> res.getClass()
==>class java.lang.String
gremlin> g.addV('domain').property(list,'language', 'English').property(list,'language', 'Kannada') .property(list,'language', 'Hindi').next()
==>v[4304]
gremlin> res = g.V(4304).properties('language').value().next()
==>English
gremlin> res.getClass()
==>class java.lang.String
spmallette
spmallette5mo ago
that is the expected output. same as what i demonstrated when calling next() in my example. i get one result of type String
gremlin> g.V(1).properties('location').value().next()
==>san diego
gremlin> g.V(1).properties('location').value().next().class
==>class java.lang.String
gremlin> g.V(1).properties('location').value().next()
==>san diego
gremlin> g.V(1).properties('location').value().next().class
==>class java.lang.String
Aiman
Aiman5mo ago
Let me brief out about my problem statement. I want to create a vertex which has property values of different data types [ex: List, String ,Map] . When I retrieve a vertex, alter gremlin command such that it returns its data type. Based on the data type i need to perform some operations from the code.
Solution
spmallette
spmallette5mo ago
A few things you should know based on your needs: 1. with JanusGraph you can't store Map or List so that may be a blocker for you 2. multi-properties aren't List - they are multiple values stored under the same property key, so those semantics may be a blocker for you 3. Gremlin has no steps that can help you detect a type. Whatever type detection you would do, it would have to happen in the client application (technically what you are doing when you call next() and class) which may be a blocker for you. 4. Using just Gremlin It's hard to detect if you are using multiproperties or not because it has no knowledge of the schema. Maybe you could consult JanusGraph for the schema for the types. Counting properties of a key doesn't really work either because you could have a key with just one property and it still could be a multiproperty (with just one value). I suppose you could: 1. try a different graph that lets you natively store a List or a Map. TinkerGraph does that but it's just an in-memory graph and may not suit your needs 2. store the type as a property value. i would think that you know the type when you are setting it with property() step, just add another property('type', 'LIST') along side it. 3. ....
Aiman
Aiman4mo ago
Thank you @spmallette
Want results from more Discord servers?
Add your server