indexOf Vertex with given property in a sorted list

Hi all! I've been trying to create a paginated GET REST api and sometimes I need to enforce a range on the resulting vertices starting from a vertex matching a given ID. Let's say my gremlin query so far returns the following list of vertices, sorted based on some property comparison:
[
V{id:Z}
V{id:F}
V{id:K}
V{id:A}
V{id:N}
V{id:T}
V{id:C}
]
[
V{id:Z}
V{id:F}
V{id:K}
V{id:A}
V{id:N}
V{id:T}
V{id:C}
]
Is there a way of asking gremlin what is the index of vertex with id K in the above list? Can all of this be done in a single query so that my final result simply returns the following, given K and a range of 3?
[
V{id:K}
V{id:A}
V{id:N}
]
[
V{id:K}
V{id:A}
V{id:N}
]
Some pseudocode for clarity:
g.V()
.hasLabel("profile")
.order()
.by("date", gremlin.process.order.asc); // at this point we have the whole list
.range(indexOf(id=K), indexOf(id=K) + 3) // this is the hiccup,
// how to find indexOf(id=K) in the sorted result
.toList()
g.V()
.hasLabel("profile")
.order()
.by("date", gremlin.process.order.asc); // at this point we have the whole list
.range(indexOf(id=K), indexOf(id=K) + 3) // this is the hiccup,
// how to find indexOf(id=K) in the sorted result
.toList()
Thank you in advance
6 Replies
VividElites
VividElites17mo ago
Couldn't you just use the range step? https://tinkerpop.apache.org/docs/current/reference/#range-step I think you would have to know the range before hand. Accoridng to the docs, if you use -1 as the 2nd argument in .range() it will emit the reamining verticies So maybe something like .range(3, -1)
neuxregime
neuxregime17mo ago
That's what I have in mind too, but I need to know the index of V{id:K} in advance so it would be something like
g.V()
.hasLabel("profile")
.order()
.by("date", gremlin.process.order.asc); // at this point we have the whole list
.range(indexOf(id=K), indexOf(id=K) + 3) // this is the hiccup,
// how to find indexOf(id=K) in the sorted result
.toList()
g.V()
.hasLabel("profile")
.order()
.by("date", gremlin.process.order.asc); // at this point we have the whole list
.range(indexOf(id=K), indexOf(id=K) + 3) // this is the hiccup,
// how to find indexOf(id=K) in the sorted result
.toList()
VividElites
VividElites17mo ago
Hmm im not sure
neuxregime
neuxregime17mo ago
no worries, appreciate the help 🙏 @spmallette @KelvinL is this even possible with gremlin? I know this can be done with 2 queries: get the list and find the index of vertex with id, then submit another query with the correct range applied. But this is not really ACID compliant, that's why I'm looking for a single-query solution
kelvinl2816
kelvinl281617mo ago
If you have the results in a list, the Gremlin index step can give you the list back with each cell having an index as well as the value. So for example:
gremlin> g.inject(['A','B','C']).index()
==>[[A,0],[B,1],[C,2]]
gremlin> g.inject(['A','B','C']).index()
==>[[A,0],[B,1],[C,2]]
Using that building block you should be able to build what you need. Often the limit and tail steps are useful when working with indexed lists. So if we have
gremlin> g.V(1,2,3).fold().index().unfold()
==>[v[1],0]
==>[v[2],1]
==>[v[3],2]
gremlin> g.V(1,2,3).fold().index().unfold()
==>[v[1],0]
==>[v[2],1]
==>[v[3],2]
we might do
gremlin> g.V(1,2,3).fold().index().unfold().where(limit(local,1).id().is(1))
==>[v[1],0]
gremlin> g.V(1,2,3).fold().index().unfold().where(limit(local,1).id().is(1))
==>[v[1],0]
and then
gremlin> g.V(1,2,3).fold().index().unfold().where(limit(local,1).id().is(1)).tail(local,1)
==>0
gremlin> g.V(1,2,3).fold().index().unfold().where(limit(local,1).id().is(1)).tail(local,1)
==>0
Similarly
gremlin> g.V(1,2,3).fold().index().unfold().where(limit(local,1).id().is(2)).tail(local,1)
==>1
gremlin> g.V(1,2,3).fold().index().unfold().where(limit(local,1).id().is(2)).tail(local,1)
==>1
neuxregime
neuxregime17mo ago
As usual, this is brilliant Kelvin. I'll put this into work and report back 🙏
Want results from more Discord servers?
Add your server