2

Imagine I have vertices with properties whose values are lists, e.g:

g.addV('v').property('prop',['a','b','c'])

How do I find cases where prop contains a certain value? This seemed the obvious thing to try:

g.V().has(P.within('prop'),'a')

But it doesn't work:

gremlin_python.driver.protocol.GremlinServerError: 599: Could not locate method: DefaultGraphTraversal.has([within([a]), test])

Edward Brown
  • 109
  • 3
  • 8

2 Answers2

3

If you use the VertexProperty list cardinality (see multi-properties in the docs), you can accomplish it like this:

>>> g.addV('v').property(list_, 'prop', 'a').property(list_, 'prop', 'b').property(list_, 'prop', 'c').next()
v[0]
>>> g.V().has('prop', within('a')).toList()
[v[0]]

Note that list_ is coming from an enum via from gremlin_python.process.traversal import Cardinality.

Jason Plurad
  • 6,682
  • 2
  • 18
  • 37
3

If it's a real list (not a multi-valued property), then you'll have to unfold the value:

gremlin> g = TinkerGraph.open().traversal()
==>graphtraversalsource[tinkergraph[vertices:0 edges:0], standard]
gremlin> g.addV('v').property('prop',['a','b','c'])
==>v[0]
gremlin> g.V().filter(values('prop').unfold().is('a'))
==>v[0]

// or

gremlin> g.V().has('prop', unfold().is('a'))
==>v[0]

Note that this filter requires a full scan over all vertices as individual list entries cannot be indexed. Hence you should take a look at Jason's answer as multi-properties are usually a much better choice.

Daniel Kuppitz
  • 10,846
  • 1
  • 25
  • 34