Reputation: 800
if I had this small graph:
addV('location').property('name','loc 1').property('active',true).property('size',2000).as('a')
addV('location').property('name','loc 2').property('active',true).property('size',1200).as('b')
addV('location').property('name','loc 3').property('active',true).property('size',1800).as('c')
addV('location').property('name','loc 4').property('active',true).property('size',2400).as('d')
addV('location').property('name','loc 5').property('active',true).property('size',2800).as('e')
addV('location').property('name','loc 6').property('active',true).property('size',4200).as('f')
addV('owner').property('name','john doe').as('o')
addV('building').property('name','building').property('active',true).as('building')
addE('on-property').from('a').to('building')
addE('owns').from('o').to('a')
addE('owns').from('o').to('b')
addE('owns').from('o').to('c')
addE('owns').from('o').to('d')
addE('owns').from('o').to('e')
addE('owns').from('o').to('f')
If I start with a base query like this:
//if 1 is the id of "john doe"
g.V(1).out('owns').has('active',true)
I want to do additional where clauses, but keep them separate so using or into a single list won't work.
The other consideration is that this is a small subset of a true graph so I don't really want to loop through them multiple times...i.e. I am thinking that a project would loop through the 1000+ locations for each projection, rather then doing a one time loop
g.V(1)
.project('sizeLimit','withBuildings')
.by(out('my-locations').where(and(has('active',true),has('size',lt(2000)))))
.by(out('my-locations').and(
coalesce(
out('on-property').count(local),
constant(0)).is(gt(0))
,has('active',true)))
I tried to do the related portions of the query first rather then having to do the "out" in each of them like:
g.V(1).out('my-locations')
.has('active',true)
.project('sizeLimit','withBuildings')
.by(has('size',lt(2000)))
.by(
coalesce(
out('on-property').count(local),
constant(0)).is(gt(0))
)
but the projection didn't take properly and ended up doing a single item per projection - even if I did a fold or unfold
So I am wondering if the first way with putting the out in the by rather then before is the only option or if I can aggregate or store the list and then do a where off that aggregate or somehow loop through and push to separate list?
I am using azure cosmos graph db.
The end look would hopefully be like this json:
"sizeLimit":[
locationVertex,
locationVertex,
locationVertex
],
"withBuildings":[
locationVertex,
locationVertex
]
The "locationVertex" being the vertex that is returned by the filter for the set of the project.
Upvotes: 1
Views: 356
Reputation: 46216
I'm not sure I fully follow your problem, but it sounds like you're mostly interested in keeping the out('owns')
from the by()
modulator because for each by()
you add you will be re-traversing the same portion of the graph. You're quite close with your second traversal example (though you say it wasn't working quite right) - with some minor modifications it seemed to behave for me:
gremlin> g.V().has('name','john doe').
......1> out('owns').has('active',true).
......2> fold().
......3> project('sizeLimit','withBuildings').
......4> by(unfold().has('size',lt(2000)).fold()).
......5> by(unfold().filter(out('on-property').count().is(gt(0))).fold())
==>[sizeLimit:[v[8],v[4]],withBuildings:[v[0]]]
I don't think you needed the coalesce()
because count()
will reduce the stream to zero when there are no outE()
edges.
Upvotes: 2