2016-06-13 5 views
3

Hier ist der Beginn meiner Abfrage.Neo4j/Cypher: Sortierergebnisse basierend auf einer sortierten Sammlung

MATCH (person:Person)<-[:NAMES]-(name:PersonName)-[:COMES_FROM]->(source:Source) 
WITH DISTINCT person, COLLECT([name, source]) AS tuples 
WITH person, REDUCE(result=[], tuple in tuples | 
    ... ) AS personName 
ORDER BY personName.lastName 
RETURN person 

Hier ist der Haken: Jede Person hat eine Reihe von Namen, die jeweils aus 1 von 5 Quellen stammen. Aber nicht alle Quellen sind gleich. Ich möchte den Namen bekommen, der von der besten Quelle kommt, wenn das nicht verfügbar ist, dann der nächstbeste usw. ["source.best", "source.very-good", "source.ok", "source.worst"] Ich möchte so etwas wie eine benutzerdefinierte Sortierung für die personName-Auflistung mit den Quellen als Prädikat durchführen und zurückgeben der erste. Es wäre einfacher, wenn die Quellen Zahlen wären oder so.

Irgendwelche Vorschläge?

Antwort

3

[√] verwenden Sie keine eindeutige und Aggregation zusammen

Sie können eine wörtliche Karte als Abbildung für Ihre Sortierung verwenden, das heißt Mapping-Strings auf Werte. Dann greifen Sie einfach den ersten (Kopf) jedes dieser Namen, wenn Sie pro Person aggregieren.

WITH {`source.best`:1, `source.very-good`:2, `source.ok`:3, `source.worst:4} as sourceSort 
MATCH (person:Person)<-[:NAMES]-(name:PersonName)-[:COMES_FROM]->(source:Source) 
WITH person, name ORDER BY sourceSort[source.name] 
RETURN person, HEAD(COLLECT(name.lastName)) AS name 
ORDER BY name 
+1

vom Chef geschlagen :) –

0

Das war sehr interessant. Ich kam auf diese Idee: punkte jede Quelle und gebe die beste zurück, die Punktzahl wird die Position ihres Wertes in einer Liste aller Quellplatzierungen sein.

Annahme:

WITH ["awesome","very-good","worst","best"] as ranking 
MATCH (person:Person)<-[:NAMES]-(name:PersonName)-[:COMES_FROM]->(source:Source) 
WITH person, name, source, 
reduce(z = 0, x IN range(0, size(ranking)-1) | 
     z + CASE source.value WHEN ranking[x] THEN x ELSE 0 END) as score 
ORDER BY person.name, score ASC 
RETURN person, collect([name, source])[0] as bestTuple 

Hinweis: die beste, mit sehr gut auf den Wert Eigenschaft des Quellknotens definiert sind Die WITH am Anfang ist ein Trick für die Simulation, dass Sie in der Regel diese als Parameter übergeben.

ich verwenden, um diese einfachen Grafik-Test:

CREATE (p:Person {name:"John"})<-[:NAMES]-(n:PersonName {name:"Jo"})-[:COMES_FROM]->(source:Source {v:"awesome"}), 
(p)<-[:NAMES]-(n2:PersonName {name:"Jonathan"})-[:COMES_FROM]->(s:Source {v:"very-good"}), 
(x:Person {name:"Xavier"})<-[:NAMES]-(n3:PersonName {name:"Xav"})-[:COMES_FROM]->(s)