2016-07-25 6 views
0

Cypher Neuling hier.Tagging Medien mit gruppierten Tags mit Neo4j und Cypher

Ich habe dieses Diagramm der markierten Medien mit dem folgenden Code erstellt.

Tagged media

CREATE 
(funny:Tag { name: 'Funny' }), 
(sad:Tag { name: 'Sad' }), 
(movie:Tag { name: 'Movie' }), 
(tv:Tag { name: 'TV Show' }), 
(hangover:Media { name: 'The Hangover' }), 
(koth:Media { name: 'King of the Hill' }), 
(simpsons:Media { name: 'The Simpsons' }), 
(twm:Media { name: 'Tuesdays with Morrie' }), 
(mm:Media { name: 'Mary & Max' }), 
(funny)-[:DESCRIBES]->(hangover), 
(funny)-[:DESCRIBES]->(koth), 
(funny)-[:DESCRIBES]->(simpsons), 
(sad)-[:DESCRIBES]->(twm), 
(sad)-[:DESCRIBES]->(mm), 
(movie)-[:DESCRIBES]->(hangover), 
(movie)-[:DESCRIBES]->(twm), 
(movie)-[:DESCRIBES]->(mm), 
(tv)-[:DESCRIBES]->(koth), 
(tv)-[:DESCRIBES]->(simpsons) 

Was ich will ist Gruppe Schlagwörter zusammen in Contexts tun, so dass ein Context-Knoten die gleiche Bedeutung wie mehrere Tags hat.

MATCH 
(tf:Tag { name: 'Funny' }), 
(tr:Tag { name: 'Sad' }), 
(tm:Tag { name: 'Movie' }) 
(tt:Tag { name: 'TV Show' }) 
CREATE 
(fm:Context { name: 'Funny Movies' }), 
(ft:Context { name: 'Funny TV' }), 
(s:Context { name: 'Sad Movies' }), 
(fm)-[:INCLUDES]->(tf), 
(fm)-[:INCLUDES]->(tm), 
(ft)-[:INCLUDES]->(tf), 
(ft)-[:INCLUDES]->(tt), 
(s)-[:INCLUDES]->(tm), 
(s)-[:INCLUDES]->(tr) 

So jetzt haben wir dieses Ding.

With Contexts

Ich möchte einen Context-Knoten zu übernehmen und Medien so erhalten, dass alle Tags in diesem Zusammenhang beschreiben jeweils Medien zurückgegeben.

Ich probierte MATCH (c:Context { name: 'Funny Movies' })-[:INCLUDES]->()-[:DESCRIBES]->(m) RETURN m, um Medien zu entsprechen, die sowohl mit Funny als auch mit Movies markiert waren. Die erwartete Ausgabe war nur The Hangover, aber ich bekomme stattdessen alle Medien.

All media

Es ist ziemlich offensichtlich, dass ich nicht verstehe, die Art der Abfrage, die ich schreiben muss. Was ist falsch an meiner Abfrage und wie kann ich die gewünschte Ausgabe erstellen?

Antwort

2

Wenn Sie von einem Kontext starten, können Sie collect die Tags und dann die Filme, die mit ALL der Tags verwandt sind übereinstimmen. Die markierten Wörter im vorhergehenden Satz sind die Schlüsselwörter für Sie als Referenz in der Neo4j Dokumentation:

MATCH (c:Context {name:"Funny Movies"})-[:INCLUDES]->(tag) 
WITH collect(tag) AS tags 
MATCH (m:Media) WHERE ALL(x IN tags WHERE (x)-[:DESCRIBES]->(m)) 
RETURN m 
+0

Schöne. Danke und akzeptiert. Ich dachte, dass die Angabe genau eines Kontexts die Ausgabe an Scheitelpunkte filtern würde, die nur mit diesem Kontext verbunden sind. Da es nicht war, was genau tat meine ursprüngliche Abfrage? –

+1

Ihre Abfrage folgt nur dem Muster, translate() zu den Knoten und [] zu den Beziehungen und Sie werden sehen, dass es 5 Muster zu verschiedenen Medien hat. –

1

Sie können die bi-direktionale Muster verwenden:

MATCH (c:Context { name: 'Funny Movies' })-[:INCLUDES]->()-[:DESCRIBES] 
     ->(m)<- 
     [:DESCRIBES]-()<-[:INCLUDES]-(c) 
RETURN m 
+0

Das ist wirklich cool! Danke für das Teilen. –