查询仅使用没有给定属性的关系

时间:2014-06-23 14:35:57

标签: neo4j cypher

cypher是否有可能不使用基于属性的某些关系?

我们有一个新的要求,即关系永远不应该被删除,但应该得到一个标志" deleted = true"所以我们有一个关于节点关系的审计跟踪。 (X之类的东西是Y的朋友,但对于所有关系类型来说有点复杂)

只需使用WHERE r.deleted = false即可在cypher查询中执行此操作,但在遍历4-5种关系类型的更复杂查询中,这可能会变得更难。

有没有一种简单的方法可以说Neo4J不应该使用与该属性的任何关系"删除"设为真?

3 个答案:

答案 0 :(得分:2)

不完全是您的要求,但您也可以将关系类型从SOMETHING更改为SOMETHING_DELETED。然后,当您指定遍历时,可以跳过这些关系。

答案 1 :(得分:1)

事实上,随着图表模型的发展,快速保持deleted属性变得无法管理:属性会逐渐渗透到您的每个查询中。据我所知,Neo4j没有提供任何帮助。

然而,我在albertoperdomo的方法上取得了成功。一些细节在几个月前的a question I asked here中。

您想要替换要删除软件的节点的两个部分:它们的标签(因此无法直接查找)及其关系(因此无法从其他节点访问它们) )。在我的例子中,我只是使用下划线(_)前缀标签和关系类型。

好处很明显:您现有的查询(可能!)是安全的,因为不再考虑软删除的节点(除非您明显省略关系类型,否则无法再将其删除,即{ {1}}或其他东西)。

我还认为这是实现软删除最高效的方式,因为您有效地切断了图表的各个部分 - 而不是在属性上进行匹配(即使它已被编入索引) )。

然而,有一个问题。 替换标签和关系没有通用的方法。你不能,例如说出以下内容:

(a)--(b)

对于您拥有的每种类型的节点,您必须单独替换每个标签和关系。如果关系是可选的,那么事情也会变得棘手,因为它很难随身携带"整个查询中的初始节点(因此my initial question)。

我解决这个问题的方法是将查询的不同部分与match (:Person {id: 123})-[r]-() set type(r) = '_' + type(r); 串在一起:

UNION

是的,你是MATCH (review:Review {Id: {id}})<-[wrote:WROTE_REVIEW]-(owner) DELETE wrote CREATE (review)<-[:_WROTE_REVIEW]-(owner) UNION MATCH (review:Review {Id: {id}})-[evaluates:EVALUATES]->(product) DELETE evaluates CREATE (review)-[:_EVALUATES]->(product) UNION ... UNION MATCH (review:Review {Id: {id}}) REMOVE review:Review") SET review:_Review; 每个子查询中的相同节点,但我认为如果你的属性被编入索引,性能影响可以忽略不计,但主要是因为你创建/读取节点比删除它们的频率高得多(否则,你的数据库将是空的!)

答案 2 :(得分:0)

像这样查询

  

(用户) - [:朋友{已删除:&#39; false&#39;}] - &gt;(f) - [:works_in {已删除:&#39; false&#39;}   ] - (公司)