我有以下SDN 4实体:
Decision
,Characteristic
和Value
:
@NodeEntity
public class Value extends Votable {
private final static String SET_FOR = "SET_FOR";
private final static String SET_ON = "SET_ON";
private final static String CONTAINS = "CONTAINS";
@Relationship(type = SET_FOR, direction = Relationship.OUTGOING)
private Decision decision;
@Relationship(type = SET_ON, direction = Relationship.OUTGOING)
private Characteristic characteristic;
@Index(unique = false)
private Object value;
...
}
我创建了3个Decicion
(Decicion1
,Decision2
,Decisison3
个)节点和1个Characteristic
(Characteristic1
)。
对于Decicion1
,Decicion2
和Characteristic1
,我创建了Double
Value
,例如:
Decision1 + Characteristic1 = Value(500d)
Decision2 + Characteristic1 = Value(1000d)
Decicion3 doesn't have any Value on Characteristic1
我需要创建一个查询,该查询将返回定义范围内Decision
的所有Value
,例如100 <= value <= 50000
根据上面的示例,此查询应仅返回Decision1
和Decicion2
。
现在我有以下查询:
MATCH (parentD)-[:CONTAINS]->(childD:Decision)-[ru:CREATED_BY]->(u:User)
WHERE id(parentD) = {decisionId}
AND ALL(key IN keys({rangeFilters})
WHERE size(
[(childD)<-[:SET_FOR]-(filterValue)-[:SET_ON]->(filterCharacteristic) WHERE id(filterCharacteristic) = toInt(key) AND ({rangeFilters}[key])[0] <= filterValue.value <= ({rangeFilters}[key])[1] | 1]
) > 0)
RETURN ru, u, childD AS decision SKIP 0 LIMIT 100
其中rangeFilters
是Map<String, Double[]>
,其中密钥为Characteristic
ID
且值为new Double[] { new Double(100.d), new Double(50000d) }
但是此查询会返回所有3个Decision
,即使Decision3
也没有与Characteristic1
相关联的任何值。
如何修复此查询以仅返回符合条件的Decisions
?
已更新
这是一个突出显示问题的示例:http://console.neo4j.org/?id=6bv9y5
已更新
我试图应用Tezra
描述的解决方案。这是我最好的疑问:
MATCH (parentD)-[:CONTAINS]->(childD:Decision)-[ru:CREATED_BY]->(u:User)
WHERE id(parentD) = {decisionId}
MATCH (childD)<-[:SET_FOR]-(filterValue)-[:SET_ON]->(filterCharacteristic)
WHERE
ALL(key IN keys({equalFilters}) WHERE id(filterCharacteristic) = toInt(key) AND filterValue.value = ({equalFilters}[key]))
AND
ALL(key IN keys({rangeFilters}) WHERE id(filterCharacteristic) = toInt(key) AND ({rangeFilters}[key])[0] <= filterValue.value <= ({rangeFilters}[key])[1])
RETURN ru, u, childD AS decision SKIP 0 LIMIT 100
不幸的是,我的测试中的断言在此查询中失败。
此查询仅在我指定单个过滤条件时才能正常工作,例如:
ALL(key IN keys({equalFilters}) WHERE id(filterCharacteristic) = toInt(key) AND filterValue.value = ({equalFilters}[key]))
或
ALL(key IN keys({rangeFilters}) WHERE id(filterCharacteristic) = toInt(key) AND ({rangeFilters}[key])[0] <= filterValue.value <= ({rangeFilters}[key])[1])
但是当它们都存在时不起作用。我做错了什么?
答案 0 :(得分:1)
根据示例数据,您只需要正确链接所有检查。 (在这个例子中,父母的东西不是,但我认为只是关键范围的一部分搞砸了你)
WITH {c1:[100,50000]} AS rangeFilters
MATCH (childD:Decision)<--(fv:FilterValue)-->(c:FilterCharacteristic)
WHERE ALL(key IN keys(rangeFilters)
WHERE c.id=key AND rangeFilters[key][0] < fv.value < rangeFilters[key][1])
RETURN childD
虽然您也可以使FilterValue成为一种关系,因为关系也可以具有属性。
更新:
关于WHERE ALL(等于...)AND ALL(in_range ...)的问题;读取&#34;其中所有相等滤波器均为真且所有范围滤波器均为真&#34;。所以我猜你真正想要的是其中任何一个是真的,哪个是(等于......)或者任何(in_range)(可用predicates),因为它不可能被过滤。值同时等于7和9。
另外,作为旁注,请勿在查询中使用id(),因为Neo4j保留根据需要更改或更改的权利。设置您自己的id字段,然后使用UUID。如果需要合并数据集,UUID也更可靠。