简体   繁体   English

通过模式理解对Neo4j Cypher节点进行过滤

[英]Neo4j Cypher node filtering by pattern comprehension

I have a following SDN 4 entities: 我有以下SDN 4实体:

Decision , Characteristic and Value : 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;

    ...
}

I have created 3 Decicion ( Decicion1 , Decision2 , Decisison3 ) nodes and 1 Characteristic ( Characteristic1 ). 我创建了3个DecicionDecicion1Decision2Decisison3 )节点和1个CharacteristicCharacteristic1 )。 For Decicion1 , Decicion2 and Characteristic1 I have created a Double Value , for example: 对于Decicion1Decicion2Characteristic1我创建了一个Double Value ,例如:

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

I need to create a query that will return all Decision which have Value in the defined range, for example 100 <= value <= 50000 我需要创建一个查询,该查询将返回所有Value在定义范围内的Decision ,例如100 <= value <= 50000

Based on the example above this query should return Decision1 and Decicion2 only. 根据上面的示例,此查询应仅返回Decision1Decicion2

Right now I have a following query: 现在我有以下查询:

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 

where rangeFilters is a Map<String, Double[]> where key is a Characteristic ID and value new Double[] { new Double(100.d), new Double(50000d) } 其中rangeFiltersMap<String, Double[]>其中key是Characteristic ID和值new Double[] { new Double(100.d), new Double(50000d) }

But this query returns all 3 Decision , even the Decision3 that don't have any values associated with Characteristic1 . 但是此查询返回所有3个Decision ,甚至没有与Characteristic1关联的值的Decision3

How to fix this query in order to return only Decisions that match a condition ? 如何修复此查询以仅返回与条件匹配的Decisions

UPDATED 更新

This is an example that highlights the issue: http://console.neo4j.org/?id=6bv9y5 这是一个突出问题的示例: http : //console.neo4j.org/?id=6bv9y5

UPDATED 更新

I'm tried to apply solution described by Tezra . 我试图应用Tezra描述的解决方案。 This is my curent query: 这是我目前的查询:

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

Unfortunately assertion in my tests fails on this query. 不幸的是,我的测试中的断言对此查询失败。

This query works fine only when I specify the single filter condition, for example: 仅当我指定单个过滤条件时,此查询才能正常工作,例如:

ALL(key IN keys({equalFilters}) WHERE id(filterCharacteristic) = toInt(key) AND filterValue.value = ({equalFilters}[key]))  

or 要么

ALL(key IN keys({rangeFilters}) WHERE id(filterCharacteristic) = toInt(key) AND ({rangeFilters}[key])[0] <= filterValue.value <= ({rangeFilters}[key])[1]) 

but doesn't work when both of them are present. 但是当两个都存在时不起作用。 What am I doing wrong ? 我究竟做错了什么 ?

Based on the example data, you just need to link all the checks correctly. 根据示例数据,您只需要正确链接所有检查即可。 (the parent stuff isn't in the example, but I think it was just the key-range part messing you up) (示例中未包含父级内容,但我认为这只是使您困惑的关键范围部分)

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

Although you could also make FilterValue a relationship since relationships can have properties too. 尽管您也可以使FilterValue成为关系,因为关系也可以具有属性。

UPDATE: 更新:

As for your problem with WHERE ALL( equals...) AND ALL(in_range...); 至于您的问题WHERE ALL(等于...)和ALL(in_range ...); That reads "Where all equal filters are true and all range filters are true". 读为“所有相等过滤器均为真,所有范围过滤器均为真”。 So I'm guessing that you actually want is any of them to be true which would be WHERE ANY (equals...) OR ANY(in_range) (available predicates ), as it is impossible for filter.value to equal 7 and 9 at the same time. 因此,我猜您实际上想要的是其中任何一个都是真实的,即WHERE ANY(等于...)或ANY(in_range)(可用谓词 ),因为filter.value不可能等于7和9与此同时。

Also, as a side note, don't use id() in your queries, as Neo4j reserves the right to change those as much or little as it likes. 另外,请注意,请勿在查询中使用id(),因为Neo4j保留根据自己的喜好或多或少更改这些内容的权利。 Set your own id fields, and use a UUID instead. 设置自己的ID字段,并改用UUID。 A UUID is also much more reliable if you need to merge data sets. 如果您需要合并数据集,则UUID也更加可靠。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM