Reputation: 7750
Data like this
a->b,c,d
b->c,d
d->a,b
Query like this
FOR n in Nodes
FOR v,e,p IN 1 ANY n GRAPH 'MyGraph'
// Only need a
// HOW TO WRITE: FILTER n have an edge to `b` and n have an edge to `d`
// This will select a,b,c
FILTER v._key in [ 'b', 'd' ]
RETURN p
I want to select a node with edge to b and d, not b or d, but how ?
EDIT
Data
insert {_key:'a'} in nodes
insert {_key:'b'} in nodes
insert {_key:'c'} in nodes
insert {_key:'d'} in nodes
insert {_from:'nodes/a',_to:'nodes/b'} into relate
insert {_from:'nodes/a',_to:'nodes/c'} into relate
insert {_from:'nodes/a',_to:'nodes/d'} into relate
insert {_from:'nodes/b',_to:'nodes/c'} into relate
insert {_from:'nodes/b',_to:'nodes/d'} into relate
insert {_from:'nodes/c',_to:'nodes/d'} into relate
A very dummy solution is
for n in nodes
for v,e,p in 1 OUTBOUND n graph 'MyGraph'
filter v._key == 'b'
for v2,e2,p2 in 1 INBOUND v graph 'MyGraph'
sort v2._key == 'd'
return v2
But this query only work for two conditions,if I need one more condition I have to write one more for
query.
Upvotes: 0
Views: 180
Reputation: 1891
I see several queries you could use. I added an vertex e
to show how they look when you have more conditions.
I. the most performant query should be:
FOR v IN 1 INBOUND 'nodes/b' graph 'MyGraph'
FILTER length(FOR d IN 1 OUTBOUND v graph 'MyGraph'
FILTER d._key == 'd'
LIMIT 1
RETURN 1) == 1
FILTER length(FOR e IN 1 OUTBOUND v graph 'MyGraph'
FILTER e._key == 'e'
LIMIT 1
RETURN 1) == 1
RETURN v
The query searchs for neighbors of b
and filters over a sub-query with the founded neighbors and checks whether they are connected with d
and e
.
II. a more transparent but also slower query:
LET b = (FOR v IN 1 INBOUND "nodes/b" graph 'MyGraph' RETURN v)
LET d = (FOR v IN 1 INBOUND "nodes/d" graph 'MyGraph' RETURN v)
LET e = (FOR v IN 1 INBOUND "nodes/e" graph 'MyGraph' RETURN v)
RETURN INTERSECTION(b, d, e)
The query makes a sub-query for every searched node and returns the intersection of their neighbors.
III. a very generic query with use of bindVars, but also the slowest:
bind parameters:
{
"targets": ["b","d","e"]
}
query:
FOR n IN nodes
LET neighbors = (FOR v,e,p IN 1 OUTBOUND n graph 'MyGraph'
FILTER v._key IN @targets
RETURN v._key)
FILTER @targets ALL IN neighbors
RETURN n
Yes, it is the slowest but you have never to change the query itself any more when you want to add more conditions. You only have to change the bind parameters.
Upvotes: 1