2014-07-02 4 views
0

est un diagramme pour vous donner ci-dessous une idée générale de la façon dont mon graphique est structuré:Neo4j: Les mauvaises performances lorsque vous faites une « jointure » sur une chaîne de nœuds

http://i.stack.imgur.com/hbn0J.png

Il contient simplement: nœuds de personne qui sont attachés à un: PersonType. Chacun: Une personne peut exprimer zéro ou plusieurs opinions. Ces opinions sont soit des opinions authentiques (: Opinion) soit des opinions empruntées à quelqu'un d'autre (: OpinionProxy). An: OpinionProxy ou un: Opinion a toujours un et un seul: relation EXPRESSÉ.

j'ai écrit une requête Cypher pour répondre à la question suivante: Donne-moi toutes les opinions exprimées par tous les « Cool Guys », et pour chaque avis, la chaîne de personnes que cette opinion est passé par.

Exemple avec les données de l'échantillon:

+--------------------+---------------------+---------------------+ 
| person    | opinion    | influence   | 
+--------------------+---------------------+---------------------+ 
| "Dan"    | o4     | "Dan"    | 
+--------------------+---------------------+---------------------+ 
| "Dan"    | o3     | "Dan", "Jim", "Jay" | 
+--------------------+---------------------+---------------------+ 
| "Bob"    | ...     | ...     | 
+--------------------+---------------------+---------------------+ 

Voici une requête qui recherche toutes les opinions de tous les "Cool Guys":

MATCH 
    (:PersonType {name: "Cool Guys"})<-[:OF_TYPE]-(p:Person)-[:EXPRESSES]->(o), 
    opath=(o)-[:REFERENCES*0..]->(op:Opinion) 
RETURN p.name AS person, op AS opinion, opath 

Jusqu'à présent, si bon. Maintenant, la partie complexe vient d'essayer de retourner la chaîne de: Personne plutôt qu'une chaîne de: OpinionProxy - [* 0 ..] ->: Opinion. Voici ma tentative:

MATCH 
    (:PersonType {name: "Cool Guys"})<-[:OF_TYPE]-(p:Person)-[:EXPRESSES]->(o), 
    opath=(o)-[:REFERENCES*0..]->(op:Opinion) 
MATCH (x)<-[:EXPRESSES]-(opAuthor:Person) 
WHERE x IN nodes(opath) 
RETURN p.name AS person, op AS opinion, collect(opAuthor) AS influence 

Cette requête renvoie exactement ce que je veux, sauf qu'il fonctionne de manière extrêmement lente .

Pour vous donner une idée, dans mon environnement de test, j'ai environ 3000: Personne (y compris 70 "Cool Guys"), 3000: Opinion et 3000: OpinionProxy. Temps de réponse:

  • Requête 1: complète dans environ 200ms
  • Requête 2: la complète dans A propos 3200ms

C'est un ordre d'augmentation de magnitude juste "rejoindre" la: personne associée à un: Opinion ou: OpinionProxy. Pour Neo4j c'est juste un pointeur à suivre et je ne m'attendais pas à voir un tel écart de performance entre ces deux requêtes.

Y at-il un problème avec ma deuxième requête? Comment puis-je l'optimiser?

Répondre

0

Vous pouvez essayer d'utiliser l'instruction WITH entre les deux instructions de correspondance. Je pense que maintenant le premier MATCH va courir encore et encore.

MATCH 
    (:PersonType {name: "Cool Guys"})<-[:OF_TYPE]-(p:Person)-[:EXPRESSES]->(o), 
    opath=(o)-[:REFERENCES*0..]->(op:Opinion) 
WITH opath,p,op 
MATCH (x)<-[:EXPRESSES]-(opAuthor:Person) 
WHERE x IN nodes(opath) 
RETURN p.name AS person, op AS opinion, collect(opAuthor) AS influence 
+0

Nous vous remercions de votre réponse. Bien que votre requête renvoie toujours l'ensemble de données correct, elle s'exécute également lentement. – Zelbus

+0

Pouvez-vous générer un plan d'exécution pour votre requête? Exécutez votre requête dans le neo4-shell précédé de "profile" comme ceci: profile MATCH (: PersonType ... –

+0

Voici le profil de la requête d'origine et de votre version: http://pastebin.com/x6T2A7MQ. beaucoup pour regarder dans cela! – Zelbus

Questions connexes