2015-12-04 13 views

risposta

16

Poiché la sintassi di ASCII-art di Cypher può solo consentire di specificare una catena lineare di connessioni in una riga, la virgola è lì, almeno in parte, per consentire di specificare le cose che potrebbero derivare. Ad esempio:.

MATCH (a)-->(b)<--(c), (b)-->(d) 

che rappresenta tre nodi che sono tutti collegati a b (due rapporti in entrata, ed una relazione uscente

La virgola può anche essere utile per separare le linee se la partita diventa troppo lungo, in questo modo:

MATCH 
    (a)-->(b)<--(c), 
    (c)-->(d) 

Ovviamente non è una linea molto lunga, ma questo è equivalente a:

MATCH 
    (a)-->(b)<--(c)-->(d) 

Ma in generale, qualsiasi istruzione MATCH specifica un modello che si desidera cercare. Tutte le parti di quello MATCH formano il modello. Nel tuo caso stai effettivamente cercando due pattern non connessi ((a)-[r]->(b) e (c)) e così Neo4j troverà ogni combinazione di ciascuna istanza di entrambi i modelli, che potrebbe essere potenzialmente molto costosa. In Neo4j 2.3 avresti probabilmente anche un avvertimento che si tratta di una query che ti darebbe un prodotto cartesiano.

Se si specificano più corrispondenze, tuttavia, si richiede di cercare motivi diversi. Quindi, se l'hai fatto:

MATCH (a)-[r]->(b) 
MATCH (c) 

Concettualmente penso che sia un po 'diverso, ma il risultato è lo stesso. So che è decisamente diverso con OPTIONAL MATCH, però. Se avete fatto:

MATCH (a:Foo) 
OPTIONAL MATCH (a)-->(b:Bar), (a)-->(c:Baz) 

Si potrebbe trovare solo i casi in cui v'è un nodo Foo collegato a nulla, o collegato sia un Bar e un nodo Baz. Mentre se si esegue questa operazione:

MATCH (a:Foo) 
OPTIONAL MATCH (a)-->(b:Bar) 
OPTIONAL MATCH (a)-->(c:Baz) 

Troverete ogni singolo Foo nodo, e avrete zero o più in contatto con Bar e Baz nodi in modo indipendente.

EDIT:

Nei commenti Stefan Armbruster fatto un buon punto che le virgole possono anche essere usati per assegnare sottopattern ai singoli identificatori. Ad esempio:

MATCH path1=(a)-[:REL1]->(b), path2=(b)<-[:REL2*..10]-(c) 

Grazie Stefan!

EDIT2: vedere anche la risposta Mats' sotto

+2

di modifica alla risposta di Brian: un altro caso d'uso per la virgola sospesa, è quello di assegnare ai singoli sottopattern identificatori, ad esempio, 'MATCH path1 = (a) - [: REL1] -> (b), path2 = (b) <- [: REL2 * .. 10] - (c)' –

10

Brian fa un buon lavoro di spiegare come la virgola può essere usato per costruire modelli sottografo più grandi, ma c'è anche un ma importante sottile differenza tra utilizzando la virgola e una seconda clausola MATCH.

Considerare il semplice grafico di due nodi con una relazione tra di loro. La query

MATCH()-->() MATCH()-->() RETURN 1 

restituirà una riga con il numero 1. Sostituire la seconda MATCH con una virgola, tuttavia, e nessuna riga sarà restituito affatto:

MATCH()-->(),()-->() RETURN 1 

Questo è a causa della nozione di univocità relazione. All'interno di ciascuna clausola MATCH, ogni relazione verrà attraversata una sola volta. Ciò significa che per la mia seconda query, l'unica relazione nel grafico verrà confrontata con il primo pattern, e il secondo pattern non sarà in grado di eguagliare nulla, portando all'intero pattern che non corrisponde. La mia prima query corrisponderà alla relazione una volta in ciascuna delle clausole e quindi creerà una riga per il risultato.

Per saperne di più su questo nel manuale Neo4j: http://neo4j.com/docs/stable/cypherdoc-uniqueness.html

+1

Ottimo punto, grazie! –