2016-07-27 164 views
1

在我的春節,數據Neo4j的項目,我有以下實體:Neo4j的暗號查詢與空或不爲空值

@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<>(); 

... 

} 

我有一個下面SDN庫方法:在此基礎上查詢

@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); 

我可以得到Criterion屬於Decision並有一個特定的名稱。

我的域模型中的標準可能(或可能不)屬於CriterionGroup

我需要擴展此查詢以添加一個條件來檢查與此標準相關的CriterionGroup。換句話說,我需要返回Criterion一個特定的{name}給一個特定的{decisionId}屬於(或不在空值的情況下)給提供的{criterionGroupId}。在{criterionGroupId} == null的情況下,我需要找到不屬於任何CriterionGroup的Criterion。

我需要的是這樣的:

@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); 

請幫我寫此查詢。

回答

1

這應該工作,而不應該是,除非你有每Criterion數萬CriterionGroups太慢:

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 

或者,你可以有2種方法在你Repository,直接管理每一種情況下使用

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

criterionGroupId爲空,並且

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 

否則。

+0

非常感謝!我將擁有與單個Criterion相關的單個CriterionGroup(不是數千!)(但我將擁有數千個Criterion,Decision和CriterionGroup)。一個CriterionGroup可以有幾十個Criterion。因此,從性能的角度來看,使用單一查詢的解決方案號碼是安全的嗎? – alexanoid

+0

您將遍歷來自'Criterion' _to_ 0或1'CriterionGroup'的標記,應該不會出現單個查詢的性能問題。 –

+0

謝謝!查詢完美無缺! – alexanoid