2013-11-15 13 views

risposta

29

Si può mettere che nella clausola WHERE:

MATCH n 
WHERE n:Male OR n:Female 
RETURN n 

EDIT

Come @tbaum sottolinea questo esegue un AllNodesScan. Ho scritto la risposta quando le etichette erano abbastanza nuovo e mi aspettavo il pianificatore query per poi implementare con un NodeByLabelScan per ogni etichetta, come avviene per il singolo caso dell'etichetta

MATCH n 
WHERE n:Male 
RETURN n 

io continuo a pensare che questo è un ragionevole espressione della query e che è ragionevole aspettarsi che il pianificatore di query lo implementa con scansioni di etichette, ma a partire da Neo4j 2.2.3 la query è ancora implementata con un AllNodesScan e un filtro di etichetta. Ecco quindi un'alternativa più prolissa. Poiché la disgiunzione dell'etichetta indica un'unione impostata e questa unione può essere espressa in modi diversi, è possibile esprimerla in modo che il pianificatore della query esegua senza eseguire la scansione di tutti i nodi e invece inizi con un NodeByLabelScan per etichetta.

MATCH (n:Male) 
WHERE n.name =~ '.ail.' 
RETURN n 
UNION MATCH (n:Female) 
WHERE n.name =~ '.ail.' 
RETURN n 

Ciò significa esprimere la query una volta per ogni etichetta e unendoli con un esplicito UNION. Questo non è irragionevole, almeno per un numero minore di etichette, ma non mi è chiaro il motivo per cui i pianificatori di query non dovrebbero essere in grado di dedurre la stessa implementazione dalla query più semplice, quindi ho aperto un problema github here.

+8

C'è un modo più breve per farlo? Ad es. per le relazioni puoi specificare '(n) - [: rel1 | rel2] -> (m) 'dove' | 'indica' OR' –

+0

No, non è possibile utilizzare un modello per le etichette e non sono a conoscenza di alcun altro modello che sia più corto o che funzioni senza una clausola 'WHERE'. Sentiti libero di inviare una richiesta di funzionalità al Neo4j [repository github] (https://github.com/neo4j/neo4j/issues). – jjaderberg

+0

@Lyman Zerga ho anche cercato in molti posti ma non avendo nulla del genere –

9
MATCH n WHERE n:Label1 OR n:Label2 

... genererà un AllNodesScan questa è una cattiva idea!

forse una soluzione migliore:

OPTIONAL MATCH (n1:Label1) 
WITH collect(distinct n1) as c1 

OPTIONAL MATCH (n2:Label2) 
WITH collect(distinct n2) + c1 as c2 

OPTIONAL MATCH (n3:Label3) 
WITH collect(distinct n3) + c2 as c3 

UNWIND c3 as nodes 
RETURN count(nodes),labels(nodes) 
+1

Perché hai bisogno di "distinti" ad ogni passaggio? –

+0

Grazie per aver segnalato "AllNodesScan", pensavo che ora sarebbe stato risolto. Ho aggiornato la mia risposta, avete qualche idea sulla mia alternativa più prolissa usando 'UNION' e come si confronta con il vostro' OPTIONAL MATCH'/'collect()'/'UNWIND'? – jjaderberg

+1

Una nota: UNION è scomodo (e in alcuni casi inutilizzabile) perché attualmente (2.2) non è possibile eseguire alcuna elaborazione con i risultati di UNION. Ad esempio, non è possibile utilizzare SKIP/LIMIT o COUNT. –

-2

documentazione per v3.0 dice questo:

si può anche descrivere un nodo che ha più etichette:

(a:User:Admin)-->(b)

Fonte: https://neo4j.com/docs/developer-manual/current/cypher/#_labels

+0

La risposta non è corretta ma non è completamente negativa, penso che l'autore abbia mancato di includere la relazione nella query ma funziona allo scopo di associare più etichette di nodi: 'MATCH (a: Utente: Admin) - [ r] -> (b) restituisce a, r, b' – artemisian

+0

FYI. L'URL di origine è leggermente cambiato. Questo è il nuovo: https://neo4j.com/docs/developer-manual/current/cypher/syntax/patterns/#_labels – Chad

+10

In realtà, questo è sbagliato, (a: User: Admin) questa query descrive quando un nodo è un "utente e anche amministratore" Nessun utente o amministratore. –

Problemi correlati