2017-03-15 1 views
0

données comme celui-ciDans ArangoDB, comment sélectionner un nœud dans le filtre graphique par multi-arête?

a->b,c,d 
b->c,d 
d->a,b 

cette requête comme

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 

Je veux sélectionner un nœud avec le bord à b et d, pas b ou d, mais comment?

EDIT

données

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 

Une solution très factice est

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 

Mais cette requête ne fonctionne que pour deux conditions, si je besoin d'une autre condition que je dois écrire une autre requête for.

Répondre

1

Je vois plusieurs requêtes que vous pourriez utiliser. J'ai ajouté un sommet e pour montrer à quoi ils ressemblent quand vous avez plus de conditions.

I. la requête doit être plus performant:

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 

La requête pour searchs voisins de b et filtres sur une sous-requête avec les voisins fondées et vérifie si elles sont liées à d et e.

II. une requête plus transparente, mais aussi plus lent:

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) 

La requête fait une sous-requête pour chaque noeud recherche et retourne l'intersection de leurs voisins.

III. une très requête générique avec l'utilisation de bindVars, mais aussi le plus lent:

paramètres de liaison:

{ 
    "targets": ["b","d","e"] 
} 

requête:

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 

Oui, il est le plus lent, mais vous devez ne jamais changer la interrogez-vous plus lorsque vous souhaitez ajouter plus de conditions. Vous n'avez qu'à changer les paramètres de liaison.