Est-ce que mes déclarations Cypher sont «surfaites»?

J'utilise py2neo avec des transactions. Cela signifie que j'utilise le langage Cypher. Je ajoute les instructions textuelles Cypher à une file d'attente de transaction et soumets le contenu de la file d'attente en une fois avec commit.

Ça fonctionne bien. Cependant, c'est lent. Je reçois environ 100/nœuds par seconde et à mesure que la file d'attente de transaction augmente, les insertions prennent plus de temps. Mon application expire si une transaction comporte plus de 6 000 nœuds (et autant de relations).

Pour l'instant je veux me concentrer sur mon Cypher. Mon application génère beaucoup de ceci:

CREATE (n:METHOD {version: 6995, unique: 682, return_type: 0, fully_qualified_name: 0, name: "method4", accessibility: 0})
CREATE (n:PARAMETER {version: 6995, unique: 687, fully_qualified_name: 0, param_type: 1, name: "param4", accessibility: 0})
MATCH (a:METHOD), (b:PARAMETER) WHERE a.unique=682 AND a.version=6995 AND b.unique=687 AND b.version=6995 CREATE (a)-[r:INVOKED_WITH]->(b)

Je crée donc un nœud METHOD, crée un nœud PARAMETER, puis les relie. Ce qui me dérange, c'est que je crée essentiellement les deux nœuds, puis je rejette le fait que je les ai simplement créés. Ensuite, je les trouve avec une recherche afin que je puisse les connecter. Cela m'irrite. La version précédente n'utilisait pas de transactions; Quand j'ai créé un nœud, j'ai récupéré un identifiant neo4j natif et je l'ai utilisé lors de la création de relations. Maintenant, je ne peux pas faire cela puisque les déclarations textuelles sont soumises en masse au serveur neo4j.

Suis-je autorisé à mettre des instructions RETURN de la manière que je peux faire dans l'interface web de neo4j? Est-il préférable d'utiliser Cypher?

EDIT - I have indexes on the "unique" property of all relevant node types.

Je n'utilise pas de paramètres dans mon code Python car le code utilise des transactions. Par conséquent, je dois utiliser le mécanisme de py2neo pour parler directement à neo4j. Cela implique de créer les commandes textuelles que vous voyez ci-dessus.

0
@ChristopheWillemsen J'ai mis à jour ma question. Voir les modifications en bas.
ajouté l'auteur Tony Ennis, source
@ChristopheWillemsen Nous utilisons py2neo. D'après ce que j'ai lu, il ne supporte pas les transactions directement.
ajouté l'auteur Tony Ennis, source
100 nœuds/seconde a l'air très lent, même en faisant un MATCH qui peut sembler inutile mais ça devrait marcher très bien. Je fais environ 1200 déclarations en 50ms environ, alors ... Avez-vous un index ou une contrainte sur toutes les propriétés sur lesquelles vous faites correspondre? utilisez-vous des paramètres dans votre code python? Pouvez-vous l'afficher?
ajouté l'auteur Christophe Willemsen, source
Je ne comprends pas votre commentaire sur les transactions, je peux utiliser python avec des transactions et utiliser des paramètres. Sans paramètres, les plans d'exécution ne peuvent pas être mis en cache, donc ..
ajouté l'auteur Christophe Willemsen, source

1 Réponses

Py2neo supporte les transactions et bien sûr vous pouvez utiliser des paramètres dans les requêtes de chiffrement, un code simple que je viens de tester:

from py2neo import Graph
import time

graph = Graph("http://neo4j:[email protected]:7474/db/data/");

tx = graph.cypher.begin()
for x in range(0,100):
    tx.append("CREATE (m:Method {id:{id}})", {"id": x})
    tx.append("CREATE (p:Parameter {id:{id}})", {"id": x})
    tx.append("MATCH (m:Method {id:{mid}}), (p:Parameter {id: {pid}}) CREATE (m)-[:RELATES]->(p)", {"mid": x, "pid": x})

mstart = int(round(time.time() * 1000))
tx.commit()
mend = int(round(time.time() * 1000))
diff = mend - mstart
print diff

Le temps de diff est d'environ 80ms

Mise à jour, vous pouvez également faire:

    tx.append("CREATE (m:Method {id:{method_id}}) WITH m
               UNWIND {parameter_ids} as p_id 
               CREATE (p:Parameter {id:p_id})
               CREATE (m)-[:RELATES]->(p)", 
              {"method_id": 1234, "parameter_ids":range(0,100)})
0
ajouté
Techniquement, py2neo ne supporte pas les transactions. C'est pourquoi vous ne pouvez pas utiliser d'objets natifs py2neo. Les bonnes personnes de py2neo ont eu la gentillesse de nous exposer l'interface Cypher. Maintenant, je comprends ce que cet attribut de paramètre est pour! Un moment pendant que je change mon code ...
ajouté l'auteur Tony Ennis, source
Votre suggestion rend le code nettement plus rapide. Je ne l'ai pas complètement mis en place donc je ne connais pas le résultat final ... mais les résultats préliminaires sont très satisfaisants.
ajouté l'auteur Tony Ennis, source
Heureusement, c'est un chargeur. Il n'y aura pas de mises à jour et tous les nœuds ont un identifiant unique. J'ai fait tous les changements maintenant, et maintenant je suis à 2200+ nœuds (avec des relations)/sec
ajouté l'auteur Tony Ennis, source
@MichaelHunger Lorsque j'exécute votre extrait (?) Dans la mise à jour, j'obtiens une erreur "WITH est requis entre CREATE et UNWIND". J'ai ajouté "AVEC m" entre eux et il a semblé fonctionner.
ajouté l'auteur Tony Ennis, source
Si vous ne faites que 2 nœuds 1 rel à la fois, vous pouvez sauvegarder la correspondance et lier directement m et p, ou un certain nombre de paramètres à une méthode avec foreach ou unwind.
ajouté l'auteur Michael Hunger, source
Vous devriez arriver à 100k/s
ajouté l'auteur Michael Hunger, source
vous pouvez également utiliser tx.append ("CREATE (m: Méthode {data})", {"data": {"id": x, "prop": "valeur"}})
ajouté l'auteur Michael Hunger, source
Btw. Tony si vous êtes intéressé il y a un Google groupe de logiciels d'analyse de graphes et de logiciels :) et ceci: neo4j.com/blog/graph-databases-and-software-metrics-analysis
ajouté l'auteur Michael Hunger, source
Techniquement, py2neo supporte les transactions. N'oubliez pas que vous pouvez également utiliser tx.process pour envoyer des instructions en file d'attente au serveur pour traitement. Ceux-ci renverront également toutes les valeurs spécifiées dans une clause WHERE afin que vous obteniez les objets Node si vous en avez besoin.
ajouté l'auteur Nigel Small, source
Cela aurait dû être la clause RETURN, pas la clause WHERE. Je n'ai pas beaucoup dormi.
ajouté l'auteur Nigel Small, source
cool, gardez également à l'esprit que CREATE ne s'occupera pas des nœuds éventuellement existants avec les mêmes identifiants, ou d'une relation existante entre vos nœuds, alors peut-être que vous voudrez regarder la clause MERGE
ajouté l'auteur Christophe Willemsen, source