2016-08-07 9 views
0

のNeo4jサイファークエリ私は、次のentititesを持っている私のSDN 4プロジェクトで

@NodeEntity 
public class Characteristic extends Authorable { 

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

    private String name; 

    private String description; 

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

} 

@NodeEntity 
public class Decision extends Commentable { 

    private final static String DEFINED_BY = "DEFINED_BY"; 

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

} 

@RelationshipEntity(type = "DECISION_CHARACTERISTIC") 
public class DecisionCharacteristic { 

    @GraphId 
    private Long id; 

    @StartNode 
    private Decision decision; 

    @EndNode 
    private Characteristic characteristic; 

    private Object value; 

} 

私は、特定の特性に合わせDecisionノードを選択する必要があります。

私は、次のサイファーのクエリ作成しました:

MATCH (parentD)-[:CONTAINS]->(childD:Decision)-[ru:CREATED_BY]->(u:User) WHERE id(parentD) = {decisionId} MATCH (childD)-[rdc:DECISION_CHARACTERISTIC]->(characteristic:Characteristic) WHERE ((( id(characteristic) = 138 AND (rdc.value > 15000.32)) AND ( id(characteristic) = 138 AND (rdc.value < 50000.32))) AND ( id(characteristic) = 139 AND (rdc.value = 'Commercial'))) WITH childD, ru, u RETURN childD 

をしかし、このクエリは、間違って動作します。私は、id=138の特性にはvalue between 15000.32 and 50000.32、決定的なノードにはid=139の特性に対しては正確にvalue = 'Commercial'を持つDecisionノードを選択する必要があります。

私のクエリで間違っていると予想どおりに動作するように変換する方法は?

 DecisionCharacteristic neo4jPriceDecisionCharacteristic = new DecisionCharacteristic(neo4jDecision, priceCharacteristic, new Double(10000.32d)); 
     decisionCharacteristicRepository.save(neo4jPriceDecisionCharacteristic); 

     DecisionCharacteristic oraclePriceDecisionCharacteristic = new DecisionCharacteristic(oracleDecision, priceCharacteristic, new Double(35000.2d)); 
     decisionCharacteristicRepository.save(oraclePriceDecisionCharacteristic); 

     assertNotNull(neo4jPriceDecisionCharacteristic); 
     assertNotNull(neo4jPriceDecisionCharacteristic.getId()); 

     DecisionCharacteristic neo4jLicenseDecisionCharacteristic = new DecisionCharacteristic(neo4jDecision, licenseCharacteristic, "Commercial"); 
     decisionCharacteristicRepository.save(neo4jLicenseDecisionCharacteristic); 

     DecisionCharacteristic orientLicenseDecisionCharacteristic = new DecisionCharacteristic(orientDecision, licenseCharacteristic, "Free"); 
     decisionCharacteristicRepository.save(orientLicenseDecisionCharacteristic); 

     DecisionCharacteristic oracleLicenseDecisionCharacteristic = new DecisionCharacteristic(oracleDecision, licenseCharacteristic, "Commercial"); 
     decisionCharacteristicRepository.save(oracleLicenseDecisionCharacteristic); 

のID:

priceCharacteristic ID: 138 
licenseCharacteristic ID: 139 

私は次のクエリでDecisionノードを取得しようとしている:

私は、次のノードを持つを更新しました

MATCH (parentD)-[:CONTAINS]->(childD:Decision)-[ru:CREATED_BY]->(u:User) WHERE id(parentD) = {decisionId} MATCH (childD)-[rdc:DECISION_CHARACTERISTIC]->(characteristic:Characteristic) WHERE (id(characteristic) = 138 AND (id(characteristic) = 138 AND ( (rdc.value > 15000.32)) AND ( (rdc.value < 50000.32))) OR ( id(characteristic) = 139 AND (rdc.value = 'Commercial'))) RETURN childD 

私だけoracleDecisionノードが、この条件に合致することを期待していますが、それは、2つのノードを返します:私が間違っている

Neo4j 
Oracle 

を?

+0

各特性のIDを説明に追加できますか?あなたは138または139でマッチングしていますが、それらが参照するものはわかりません。 – InverseFalcon

+0

私は質問を更新しました:priceCharacteristic ID:138 licenseCharacteristic ID:139 – alexanoid

答えて

1

クエリの主な欠陥は、ANDを使用して不可能なwhere句を作成することです。文字通りidが2つの異なる数字で、rdc.valueが複数の値で同時に値を返すように要求しています...不可能です。正しい場所ではなく、ORを使用して、1つのIDまたは別のIDで一致させる必要があります。また、rdc.valueの制限を改善することもできます。

MATCH (parentD)-[:CONTAINS]->(childD:Decision)-[ru:CREATED_BY]->(u:User) 
WHERE id(parentD) = {decisionId} 
MATCH (childD)-[rdc:DECISION_CHARACTERISTIC]->(characteristic:Characteristic) 
WHERE (id(characteristic) = 138 AND (15000.32 < rdc.value < 50000.32)) 
OR (id(characteristic) = 139 AND (rdc.value = 'Commercial')) 
WITH childD, ru, u 
RETURN childD 

最後に、childDを返すだけなので、WITH句はまったく必要ありません。あなたが戻り値で他の変数を返すのを忘れたからだと確信していますが、あなたが本当にchildDを返すだけなら、あなたのWITH句とあなたの最初の行の一致のruとu変数を取り除くことができます。 If:決定は常にユーザーによって作成されますが、 " - [ru:CREATED_BY] - >(u:User)"を取り除くことで最初の試合をトリミングすることができます。これは、クエリが見えるようになります。

MATCH (parentD)-[:CONTAINS]->(childD:Decision) 
WHERE id(parentD) = {decisionId} 
MATCH (childD)-[rdc:DECISION_CHARACTERISTIC]->(characteristic:Characteristic) 
WHERE (id(characteristic) = 138 AND (15000.32 < rdc.value < 50000.32)) 
OR (id(characteristic) = 139 AND (rdc.value = 'Commercial')) 
RETURN childD 

EDIT

ああ、大丈夫、それはあなたが両方の特性や場所の制限の二つの異なるタイプに一致させたいあなたのクエリから明確ではありませんでした。その場合、特性との一致が1回では不十分です。それらを別々に指定する必要があります。

MATCH (parentD)-[:CONTAINS]->(childD:Decision)-[:CREATED_BY]->(:User) 
WHERE id(parentD) = {decisionId} 
MATCH (childD)-[pdc:DECISION_CHARACTERISTIC]->(priceChar:Characteristic) 
WHERE (id(priceChar) = 138 AND (15000.32 < pdc.value < 50000.32)) 
MATCH (childD)-[ldc:DECISION_CHARACTERISTIC]->(licenseChar:Characteristic) 
WHERE (id(licenseChar) = 139 AND (ldc.value = 'Commercial')) 
RETURN childD 

このようにグラフをモデリングするのは本当に大丈夫ですか?特性ノードがありますが、ノード自体の代わりに特性データを関係に保存しています。PriceCharacteristicやLicenseCharacteristicなどの別々のタイプが実際にあるように見える場合は、単一の特性ノードも使用しています。これを行うための要件や理由がありますか、グラフデータの表現方法を自由に変更できますか?

+0

ありがとう!私は私の質問を更新しました。クエリが期待どおりに動作しません。 – alexanoid

+0

明確な要件を満たすために私の答えが更新されました。 – InverseFalcon

+0

ありがとう!このスキームの理由について別の私の質問を参照してくださいhttp://stackoverflow.com/questions/38639178/spring-data-neo4j-4-and-dynamic-product-properties – alexanoid

関連する問題