Neo4j:与深度关系的条件

时间:2013-11-07 21:53:09

标签: neo4j cypher

我正在尝试做什么

相对较新的Neo4j,我正在尝试在 Neo4j 图形数据库中找到 Cypher 的某些节点。节点应通过某种类型的关系链与关系上的条件进一步连接

// Cypher
START self = node(3413)
MATCH (self)<-[rel:is_parent_of*1..100]-(ancestors)
WHERE rel.some_property = 'foo'
RETURN DISTINCT ancestors

出了什么问题

如果我删除深度部分*1..100,则查询有效,但当然只允许selfancestors之间的一个关系。

但是,如果我通过引入深度ancestors允许self*1..100几步之遥,则查询失败:

错误:预期rel为地图,但它是一个集合

我想,也许这种语法将rel定义为is_parent_of*1..100,而不是将rel定义为类型is_parent_of的关系,并允许更大的关系深度。

所以,我试图通过使用括号来表达我的意图:[(rel:is_parent_of)*1..100。但这会导致语法错误

我很感激有任何帮助来解决这个问题。谢谢!

1 个答案:

答案 0 :(得分:8)

命名法

调用*1..100 深度源于neography ruby gem的命名法,使用抽象depth方法完成此操作。

在neo4j中,这称为可变长度关系,如文档中所示:MATCH / Variable length relationships

错误原因

预期rel是地图,但它是集合”错误的原因确实是rel并未引用每个单独的关系,而是整个匹配关系的集合。

有关示例,请参阅文档中的MATCH / Relationship variable in variable length relationships

解决方案

首先,确认标识符引用了一个集合(即一组多个项目)并将其称为rels而不是rel。然后,在WHERE子句中,使用ALL predicate声明条件必须应用于rel集合中的所有rels项。

// Cypher
START self = node(3413)
MATCH (self)<-[rels:is_parent_of*1..100]-(ancestors)
WHERE ALL (rel in rels WHERE rel.some_property = 'foo')
RETURN DISTINCT ancestors

ALL谓词在文档中解释:Functions / Predicate Functions

我通过this stackoverflow answer相关问题引出了这个解决方案。

查询时间长

不幸的是,要求关系属性确实需要花费大量时间。上面的查询只包含数据库中的几个节点,在我的开发机器上需要超过3000毫秒。