2016-07-27 19 views
1

In meinem Spring Data Neo4j Projekt habe ich eine folgende Einheit:Neo4j Cypher Abfrage mit null oder nicht null Wert

@NodeEntity 
public class Decision extends Commentable { 

    private final static String CONTAINS = "CONTAINS"; 
    private final static String DEFINED_BY = "DEFINED_BY"; 

    private String name; 

    @Relationship(type = DEFINED_BY, direction = Relationship.INCOMING) 
    private Set<CriterionGroup> criterionGroups = new HashSet<>(); 

    @Relationship(type = DEFINED_BY, direction = Relationship.INCOMING) 
    private Set<Criterion> criteria = new HashSet<>(); 

... 

} 

@NodeEntity 
public class Criterion extends Authorable { 

    private final static String CONTAINS = "CONTAINS"; 
    private final static String DEFINED_BY = "DEFINED_BY"; 

    private String name; 

    @Relationship(type = CONTAINS, direction = Relationship.INCOMING) 
    private CriterionGroup group; 

    @Relationship(type = DEFINED_BY, direction = Relationship.OUTGOING) 
    private Decision owner; 

... 

} 

@NodeEntity 
public class CriterionGroup extends Authorable { 

    private final static String DEFINED_BY = "DEFINED_BY"; 
    private final static String CONTAINS = "CONTAINS"; 

    private String name; 

    @Relationship(type = DEFINED_BY, direction = Relationship.OUTGOING) 
    private Decision owner; 

    @Relationship(type = CONTAINS, direction = Relationship.OUTGOING) 
    private Set<Criterion> criteria = new HashSet<>(); 

... 

} 

Ich habe folgende SDN-Repository-Methode:

@Query("MATCH (d:Decision)<-[:DEFINED_BY]-(c:Criterion) WHERE id(d) = {decisionId} and c.name = {name} RETURN c") 
Criterion findCriterionDefinedByDecisionByName(@Param("decisionId") Long decisionId, @Param("name") String name); 

auf dieser Abfrage Basierend Ich kann Criterion erhalten, das zu Decision gehört und einen spezifischen Namen hat.

Das Kriterium in meinem Domänenmodell kann (oder darf nicht) zu CriterionGroup gehören.

Ich muss diese Abfrage erweitern, um eine weitere Bedingung für die Überprüfung CriterionGroup mit diesem Kriterium verbunden hinzuzufügen. Mit anderen Worten, ich muss Criterion mit einem bestimmten {Name} für eine bestimmte {DecisionId} zurückgeben, die zu einer angegebenen {criterionGroupId} gehört (oder nicht im Falle eines Nullwerts). Im Falle von {criterionGroupId} == null muss ich Criterion finden, das keinem CriterionGroup gehört.

Ich brauche etwas wie folgt aus:

@Query("MATCH (d:Decision)<-[:DEFINED_BY]-(c:Criterion)...????????...... WHERE id(d) = {decisionId} and c.name = {name} RETURN c") 
Criterion findCriterionDefinedByDecisionByName(@Param("decisionId") Long decisionId, @Param("name") String name, @Param("criterionGroupId") Long criterionGroupId); 

Bitte helfen Sie mir, diese Abfrage zu schreiben.

Antwort

1

Dies sollte funktionieren, und sollte nicht zu langsam sein, entweder, wenn Sie Zehntausende von CriterionGroups pro Criterion haben:

MATCH (d:Decision)<-[:DEFINED_BY]-(c:Criterion) 
WHERE id(d) = {decisionId} 
    AND c.name = {name} 
OPTIONAL MATCH (c)<-[:CONTAINS]-(cg:CriterionGroup) 
WITH c, extract(g IN collect(cg) | id(g)) AS cgIds 
WHERE CASE 
     WHEN {criterionGroupId} IS NULL THEN size(cgIds) = 0 
     ELSE {criterionGroupId} IN cgIds 
     END 
RETURN c 

Alternativ Sie 2 Methoden in Ihrem Repository haben könnte, jeden Fall direkt zu verwalten unter Verwendung

MATCH (d:Decision)<-[:DEFINED_BY]-(c:Criterion) 
WHERE id(d) = {decisionId} 
    AND c.name = {name} 
    AND NOT (c)<-[:CONTAINS]-(:CriterionGroup) 
RETURN c 

wenn criterionGroupId null ist, und

MATCH (d:Decision)<-[:DEFINED_BY]-(c:Criterion), 
     (c)<-[:CONTAINS]-(cg:CriterionGroup) 
WHERE id(d) = {decisionId} 
    AND c.name = {name} 
    AND id(cg) = {criterionGroupId} 
RETURN c 

ansonsten.

+0

Vielen Dank! Ich werde eine einzige CriterionGroup (nicht Tausende!) Mit einem einzigen Kriterium verknüpfen (aber ich werde Tausende von Kriterien, Entscheidungen und CriterionGroup haben). Eine CriterionGroup kann ein paar Dutzend Criterion haben. Auf diese Weise ist es vom Standpunkt der Leistung aus sicher, die Lösung Nummer eins mit einer einzigen Abfrage zu verwenden? – alexanoid

+0

Sie werden _von_Criterion_ _nach_ 0 oder 1 'CriterionGroup' durchlaufen, es sollte kein Performance-Problem mit der einzelnen Abfrage geben. –

+0

Danke! Die Abfrage funktioniert einwandfrei! – alexanoid