2017-10-05 5 views
1

je disposer de données organisées de telle manière:Arangodb requête AQL

enter image description here

Il y a 1k des enseignants, des élèves 10k, chaque élève a environ 100 HomeWorks.

J'ai besoin de tous les devoirs d'élèves, liés à un enseignant via des cours, ou par lien direct entre eux. Tous les sommets et arêtes ont des attributs, et supposons que tous les indices requis sont déjà construits, ou nous pouvons en discuter un peu plus tard.

je peux obtenir tous les élèves ids par cette requête assez rapide requis:

$query1 = "FOR v1 IN 1..1 INBOUND @teacherId teacher_pupil FILTER v1.deleted == false RETURN DISTINCT v1._id"; 
$query2 = "FOR v2 IN 2..2 INBOUND @teacherId OUTBOUND teacher_class, INBOUND pupil_class FILTER v2.deleted == false RETURN DISTINCT v2._id"; 
$queryUnion = "FOR x IN UNION_DISTINCT (($query1), ($query2)) RETURN x"; 

Alors j'écrit ce qui suit:

$query = " 
LET pupilIds = ($queryUnion) 

FOR pupilId IN pupilIds 
    LET homeworks = (
     FOR homework IN 1..1 ANY pupilId pupil_homework 
      return [homework._id, pupilId] 
    ) 
RETURN homeworks"; 

Je suis mes devoirs, et je peux même essayer de les filtrer, mais la requête est trop lente - c'est une façon incorrecte, je crois.

Question 1 Comment puis-je le faire sans que tous les Homeworks aient une quantité importante de mémoire à la fois (LIMIT ou autre), en triant et en filtrant Homeworks par vertex 'attributs rapidement et efficacement? Je suis sûr que la limitation des élèves ou des devoirs liés à la pupille dans la requête/sous-requête FOR entraîne un mauvais tri/pagination.

j'ai fait un autre essai avec pur graphique AQL requête:

$query1 = "FOR v1 IN 2..2 INBOUND @teacherId pupil_teacher, OUTBOUND pupil_homework RETURN v1._id"; 
$query2 = "FOR v2 IN 3..3 INBOUND @teacherId teacher_class, pupil_class, OUTBOUND pupil_homework RETURN v2._id"; 
$query = "FOR x IN UNION_DISTINCT (($query1), ($query2)) LIMIT 500, 500 RETURN x"; 

Il est beaucoup plus rapide, et je ne sais pas comment le filtre sommets de l'enseignant par attributs.

Question 2 Quelle approche est la meilleure pour construire de telles requêtes AQL, comment puis-je accéder aux sommets d'un graphe filtrant toutes les parties du chemin par attributs? Puis-je paginer le résultat pour économiser de la mémoire et accélérer la requête? Comment puis-je l'accélérer du tout?

Merci!

Répondre

1

En supposant enseignant et l'élève sont liés entre eux par des classes (2 liens sortants) ou directement (seul lien sortant) et sans autre façon que vous pouvez faire quelque chose comme ça

FOR v IN 1..2 OUTBOUND "teacher_id" GRAPH "graph_name" 
    FILTER LIKE(v._id, "pupil_collection_name/%") 
    FOR homeworks IN 1 OUTBOUND v GRAPH "graph_name" 
     LIMIT lowerLimit,numberOfItems 
      RETURN homeworks 

Mais si est une possibilité qu'un enseignant et l'élève peuvent être reliés les uns aux autres avec autre chose qu'une classe nous devrions filtrer notre requête par rapport au bord, nous voyons aussi bien

FOR v IN 1..2 OUTBOUND "teacher_id" GRAPH "graph_name" 
    FILTER LIKE(v._id, "pupil_collection_name/%") && (e.name == "ClassPupil" || e.name == "TeacherPupil") 
    FOR homeworks IN 1 OUTBOUND v GRAPH "graph_name" 
     LIMIT lowerLimit,numberOfItems 
      RETURN homeworks 

Notez que depuis même te acher peut être lié directement à un élève ainsi que par le biais d'une classe, nous pouvons avoir des devoirs non uniques. Par conséquent, l'utilisation d'un RETURN DISTINCT homeworks est suggérée. Mais si les duplications ne sont pas un problème, la requête ci-dessus devrait fonctionner

+0

Merci pour la réponse: la requête est très rapide. Que faire si je veux un filtre par attribut de devoirs? Il suffit d'ajouter ... POUR EN 1 SORTANT HomeWorks v GRAPH "graph_name" ** FILTRE homeworks.attr1 == 'valeur1' ** LIMITE LOWERLIMIT, numberOfItems RETOUR ... homeworks est trop lent, et, comme je le sais, pour les requêtes graphiques ArangoDB n'utilise pas les index d'attributs de vertex. – anton

+0

Si vous voulez juste filtrer les devoirs par l'attribut de devoirs, vous pouvez simplement boucler dans la collection de devoirs sans avoir besoin d'utiliser une requête graphique. 'FOR hw dans home_work_collection_name FILTRE hw.attr1 == 'valeur1' renvoie hw'. De plus, il est suggéré d'indexer votre collection par l'attribut 'attr1'. Une fois que vous avez vos devoirs filtrés, vous pouvez parcourir le graphique et obtenir les informations de l'enseignant ou des classes en conséquence. Inversement (suggéré) vous pouvez ajouter un 'filtre' dans la requête qui est dans la réponse ci-dessus. Juste au-dessus de la ligne 'LIMIT lowerLimit, numberOfItems' – Prasanna