2016-07-27 4 views
1

:このクエリに基づいてのNeo4jサイファークエリ私は次のエンティティを持っている私の春データのNeo4jプロジェクトで

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

@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リポジトリメソッドを持っていますDecisionに属していて、特定の名前を持っているCriterionを得ることができます。

私のドメインモデルの基準は、CriterionGroupに属している場合もあれば、そうでない場合もあります。

CriterionGroupをこの条件に関連付けてチェックする条件をもう1つ追加するには、このクエリを拡張する必要があります。言い換えれば、指定された{criterionGroupId}に属している特定の{decisionId}(特定の{name}の{null}の値ではない場合)に特定の{name}を持つCriterionを返す必要があります。 {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 

また、あなたは直接それぞれのケースを管理するために、あなたの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 
使用それ以外の場合は

です。

+0

ありがとうございました! 1つのCriterionに関連付けられたCriterionGroup(数千ではありません)を1つ持っていきます(ただし、何千ものCriterion、Decision、CriterionGroupを持っています)。 1つのCriterionGroupは数十のCriterionを持つことができます。したがって、このようにパフォーマンスの観点からは、ソリューション番号1を単一のクエリで使用することは安全ですか? – alexanoid

+0

あなたは 'Criterion' _to_ 0または1' CriterionGroup'から辿りつきますので、単一のクエリではパフォーマンス上の問題はありません。 –

+0

ありがとう!クエリは完全に機能します! – alexanoid

関連する問題