在我的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
个节点。
我创建了以下Cypher查询:
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'
。
我的查询错误,如何转换以便按预期工作?
已更新
我有以下节点:
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
节点匹配此条件,但它返回两个节点:
Neo4j
Oracle
我哪里错了?
答案 0 :(得分:1)
查询中的主要缺陷是使用AND来创建一个不可能的where子句。你实际上要求它返回id为两个不同数字的值,并且rdc.value同时是多个值...不可能。您需要在正确的位置使用OR,以便您可以匹配一个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
最后,您根本不需要WITH子句,因为您只返回childD。不确定是否因为你忘了在返回中返回其他变量,但是如果你真的只返回childD,那么你可以消除你的WITH子句,以及你的第一个中的ru和u变量线路匹配。如果:决策总是由用户创建,那么您可以通过删除&#34; - [ru:CREATED_BY] - &gt;(u:用户)&#34;来修剪您的第一场比赛。这会使您的查询看起来像:
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
修改
啊,好吧,从您的查询中可以清楚地知道您想要匹配两种不同类型的特征并对两者都设置限制。在这种情况下,针对特征的单一匹配是不够的。您需要单独指定它们。
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等。您是否有要求或有充分理由这样做,或者您是否可以自由更改图表数据的表示方式?