【问题标题】:Neo4j Cypher query with null or not null value具有空值或非空值的 Neo4j Cypher 查询
【发布时间】:2016-07-27 14:37:15
【问题描述】:

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

基于此查询,我可以获得属于 Decision 并具有特定名称的 Criterion

我的域模型中的标准可能(或可能不)属于CriterionGroup

我需要扩展此查询以添加一个更多条件来检查与此标准关联的CriterionGroup。换句话说,我需要为特定的 {decisionId} 返回具有特定 {name} 的标准,该特定 {decisionId} 属于(或在 null 值的情况下不属于)提供的 {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);

请帮我写这个查询。

【问题讨论】:

    标签: neo4j spring-data cypher spring-data-neo4j


    【解决方案1】:

    这应该可以工作,而且也不应该太慢,除非你有数以万计的CriterionGroupsCriterion

    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 为空时,并且

    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
    

    否则。

    【讨论】:

    • 非常感谢!我将拥有一个与单个 Criterion 相关联的 CriterionGroup(不是数千个!)(但我将拥有数千个 Criterion、Decision 和 CriterionGroup)。一个 CriterionGroup 可以有几十个 Criterion。那么从性能的角度来看,以这种方式在单个查询中使用第一个解决方案是否安全?
    • 您将遍历 from Criterion to 0 或 1 CriterionGroup,应该不会出现性能问题单个查询。
    猜你喜欢
    • 2016-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多