2016-06-28 12 views
3

Ich habe ein großes Diagramm, in dem Knoten für Personen stehen. Alle von ihnen haben Vornamen und Nachnamen Eigenschaften, einige haben Middename Eigenschaften. Ich suche nach Knoten, die dieselbe Person repräsentieren könnten, also schaue ich auf die verschiedenen Permutationen von Namen. Ich vergleiche gerade Nachnamen und die erste Initiale von Vornamen [einige Knoten haben nur Initialen], können aber nicht herausfinden, wie man Zwischennamen testet, wenn sie existieren.Neo4j Cypher - Vergleiche Eigenschaftswerte, wenn sie existieren?

Meine aktuelle Abfrage ist:

match (a:Author), (b:Author) 
where 
    a.surname=b.surname and 
    (a.firstname starts with 'A' and b.firstname starts with 'A') 
return distinct a,b 

Mein Verständnis ist, dass OPTIONAL MATCH nur auf Muster bezieht, so dass wird nicht funktionieren. Ich kann keine Möglichkeit finden, eine if-Anweisung zu schreiben, die Sinn ergibt.

Es mag sein, dass es für mich sinnvoller ist, dies programmatisch zu tun, anstatt mich nur auf direkte Cypher-Abfragen zu verlassen, aber ich hoffte, es wirklich einfach zu halten und es einfach in Cypher zu machen.

Einige Beispiele, um zu verdeutlichen, was ich tun möchte.

Beispiel 1:

Node 1: firstname "John" middlename "Patrick" lastname "Smith" 
    Node 2: firstname "J" middlename "P" lastname "Smith" 
    Node 3: firstname "J" middlename "Q" lastname "Smith" 
    Node 4: firstname "J" lastname "Smith" 

möchte ich eine Abfrage, die 1 Knoten zurück, 2 und 4 als 'Matching'.

Beispiel 2:

Node 1: firstname "Jane" lastname "Smith" 
Node 2: firstname "J" middlename "P" lastname "Smith" 
Node 3: firstname "J" middlename "Q" lastname "Smith" 
Node 4: firstname "J" lastname "Smith" 

Hier möchte ich alle vier Knoten, da die 'kanonischen' Name keinen zweiten Vornamen haben.

+0

Sie möchten vielleicht deutlicher erklären, was es ist Sie versuchen, da „zu tun, kann nicht herausfinden, wie Mittelnamen testen wenn es sie gibt "führte ich dazu, dass ich dir sage, dass du" EXISTS "benutzen sollst und dafür abgestimmt wirst. – joslinm

+0

Danke, hoffentlich verdeutlichen meine erweiterten Beispiele besser. FWIW, ich habe dich nicht abgelehnt. Ihr Kommentar war für mich ein Zeichen dafür, dass ich das Problem, das ich lösen wollte, nicht klar erklärt habe. – betseyb

Antwort

2

Ich glaube, Sie brauchen etwas wie folgt aus:

match (a:Author), (b:Author) 
where 
    id(a) < id(b) and 
    (a.surname=b.surname) and 
    (a.firstname starts with 'A' and b.firstname starts with 'A') and 
    (a.middlename=b.middlename OR a.middlename IS NULL OR b.middlename IS NULL) 
return a,b 

How to work with null ist eine gute Referenz für Rätsel, wie die, die Sie mit zu tun haben.

EDIT: Lassen Sie uns es brechen mit einigen Pseudo-Code unten:

if (a.middlename is null) return true; 
if (b.middlename is null) return true; 
if (a.middlename is not null and b.middlename is not null and a.middlename!=b.middlename) return false; 
if (a.middlename is not null and b.middlename is not null and a.middlename=b.middlename) return true; 
+0

Dies ist nicht der richtige Ansatz. – joslinm

+0

Gibt es einen Grund für diese Behauptung? Ich kann es im Moment nicht selbst testen. – Sevle

+0

Von dem, was ich von den etwas unverständlichen Anforderungen verstehe, will das OP Leute vergleichen, die beide einen Vornamen haben und Leute vergleichen, die beide keinen Vornamen haben. Die letzte Klausel, die Sie hinzugefügt haben, entspricht im Grunde allen, es sei denn, sie haben genau den gleichen Vornamen (seltsam?) Oder wenn einer von ihnen null ist. – joslinm