通过模式理解过滤Neo4j Cypher节点

时间:2017-05-08 18:56:37

标签: neo4j cypher

我有以下SDN 4实体:

DecisionCharacteristicValue

@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个DecicionDecicion1Decision2Decisison3个)节点和1个CharacteristicCharacteristic1)。 对于Decicion1Decicion2Characteristic1,我创建了Double Value,例如:

Decision1 + Characteristic1 = Value(500d)
Decision2 + Characteristic1 = Value(1000d)
Decicion3 doesn't have any Value on Characteristic1

我需要创建一个查询,该查询将返回定义范围内Decision的所有Value,例如100 <= value <= 50000

根据上面的示例,此查询应仅返回Decision1Decicion2

现在我有以下查询:

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 

其中rangeFiltersMap<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]) 

但是当它们都存在时不起作用。我做错了什么?

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也更可靠。