具有空值或非空值的 Neo4j Cypher 查询

Neo4j Cypher query with null or not null value

在我的 Spring Data 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);

基于这个查询,我可以得到属于 DecisionCriterion 并且有一个特定的名称。

我的领域模型中的条件可能(或可能不)属于 CriterionGroup

我需要扩展此查询以添加一个条件来检查与此标准关联的 CriterionGroup。换句话说,我需要 return 具有特定 {name} 的标准,用于特定 {decisionId},该 {decisionId} 属于(或者在空值的情况下不属于)提供的 {criterionGroupId}。在 {criterionGroupId} == null 的情况下,我需要找到不属于任何 CriterionGroup.

的标准

我需要这样的东西:

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

请帮我写这个查询。

这应该可行,而且应该不会太慢,除非你有数以万计的 CriterionGroups 每个 Criterion:

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

或者,您可以在 Repository 中使用 2 种方法来直接管理每个案例,使用

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

criterionGroupId 为 null 且

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

否则。