2013-06-06 6 views
5

Sto cercando di inserire un gran numero di nodi (~ 500.000) in un database neo4j (non incorporato) eseguendo i comandi di cypher usando py2neo python modulo (py2neo.cypher.execute). Alla fine ho bisogno di rimuovere la dipendenza da py2neo, ma lo sto usando al momento fino a quando non imparerò di più su cypher e neo4j.Qual è il modo più efficiente per inserire i nodi in un database neo4j utilizzando la cifratura

Ho due tipi di nodo A e B e la maggior parte dei nodi è di tipo A. Esistono due possibili relazioni r1 e r2, tali che A- [r1] -A e A- [r2] -B . Ogni nodo di tipo A avrà relazioni 0 - 100 r1 e ogni nodo di tipo B avrà relazioni 1 - 5000 r2.

Al momento sto inserendo nodi creando grandi istruzioni CREATE. Per esempio potrei avere una dichiarazione

CREATE (:A {uid:1, attr:5})-[:r1]-(:A {uid:2, attr:5})-[:r1]-... 

dove ... potrebbe essere un altro 5000 o giù di lì i nodi e le relazioni che formano una catena lineare nel grafico. Funziona bene, ma è piuttosto lento. Sto anche l'indicizzazione di questi nodi utilizzando

CREATE INDEX ON :A(uid) 

Dopo che ho aggiungere tutti i nodi di tipo A, aggiungo i nodi di tipo B e che utilizzano CREATE nuovo dichiarazioni. Infine, sto cercando di aggiungere le relazioni r2 usando una dichiarazione come

MATCH c:B, m:A where c.uid=1 AND (m.uid=2 OR m.uid=5 OR ...) 
CREATE (m)-[:r2]->(c) 

dove ... potrebbe rappresentare alcune migliaia di istruzioni OR. Questo sembra davvero lento, aggiungendo solo poche relazioni al secondo.

Quindi, c'è un modo migliore per farlo? Sono completamente fuori strada qui? Ho guardato su this question ma questo non spiega come usare Cypher per caricare in modo efficiente i nodi. Tutto il resto che guardo sembra usare java, senza mostrare le effettive query che potrebbero essere usate.

risposta

6

Non creare l'indice fino alla fine (in 2.0). Rallenterà la creazione del nodo.

Stai usando i parametri nel tuo Cypher?

Immagino tu stia perdendo un sacco di tempo di analisi del cypher a meno che il tuo cifrario non sia esattamente lo stesso ogni volta con i parametri. Se puoi modellarlo in questo modo, vedrai un marcato aumento delle prestazioni.

Stai già inviando pezzi abbastanza pesanti nella tua richiesta di cifratura, ma l'API di richiesta batch ti consente di inviare più di una richiesta REST, che potrebbe essere più veloce (provalo!).

Infine, se si tratta di un'importazione una tantum, si potrebbe prendere in considerazione l'utilizzo dello strumento di importazione batch, in grado di masterizzare nodi 500K in pochi minuti anche su hardware non valido ... quindi è possibile aggiornare i file di database (Non penso che possa ancora creare file 2.0, ma a breve potrebbe arrivare a breve, e creare le tue etichette/indice tramite Cypher.

Aggiornamento: Ho appena notato la tua dichiarazione MATCH alla fine. Non dovresti farlo in questo modo: fai una relazione alla volta invece di usare l'OR per gli id. Questo probabilmente aiuterà molto - e assicurati di usare i parametri per gli uids. Cypher 2.0 non sembra essere in grado di fare ricerche di indice con OR, anche quando si utilizza un suggerimento indice. Forse questo verrà dopo.

Aggiornamento dicembre 2013: 2.0 ha l'endpoint transazionale Cypher, su cui ho riscontrato miglioramenti di grande throughput.Sono stato in grado di inviare dichiarazioni Cypher di 20-30k/secondo, utilizzando le dimensioni "exec" di 100-200 dichiarazioni e le dimensioni delle transazioni di 1000-10000 istruzioni totali. Molto efficace per accelerare il caricamento su Cypher.

+1

Desidero aggiungere commenti Wes: parametri, istruzioni più piccole, se si utilizza 2.0 considerare l'utilizzo dell'endpoint transazionale http per cypher, vedere: http://neo4j.org/develop/labels per cypher & import vedere: http: //www.neo4j.org/develop/import e http://jexp.de/blog/2013/05/on-importing-data-in-neo4j-blog-series/ –

+0

Grazie per il consiglio. Sai come posso usare i parametri con le dichiarazioni CREATE di cypher da Python? Tutto ciò che sono stato in grado di trovare sui parametri sta parlando delle mappe di hash di Java. – savagent

+0

In py2neo è un parametro del dizionario chiamato params. http://book.py2neo.org/en/latest/cypher.html Se stai facendo solo JSON raw su HTTP, puoi aggiungere un parametro: {uid: ...} alla richiesta JSON, con query. –