我有节点的分层结构,它们都具有一个自定义的分配排序属性(数字)限制查询。这里有一个简单的Cypher查询重现:的Neo4j - 基于节点的排名
merge (p {my_id: 1})-[:HAS_CHILD]->(c1 { my_id: 11, sort: 100})
merge (p)-[:HAS_CHILD]->(c2 { my_id: 12, sort: 200 })
merge (p)-[:HAS_CHILD]->(c3 { my_id: 13, sort: 300 })
merge (c1)-[:HAS_CHILD]->(cc1 { my_id: 111 })
merge (c2)-[:HAS_CHILD]->(cc2 { my_id: 121 })
merge (c3)-[:HAS_CHILD]->(cc3 { my_id: 131 });
我挣扎的问题是,我常常需要根据相对于一些父节点的子节点上排名的决定,与regads到这种标识。因此,例如,节点c1
相对于节点p
具有1级(因为它具有最小sort
属性),c2
具有等级2,并且c3
具有等级3(最大sort
)。
那种决定我需要根据这些信息:显示孩子只有前2个cX
节点。这里就是我想:
cc1
和cc2
都存在,但cc3
是不是因为c3
(其父)不是第一或p
的第二个孩子。下面是一个哑巴查询:
match (p {my_id: 1 })-->(c)
optional match (c)-->(cc) where c.sort <= 200
return p, c, cc
问题是,这些sort
属性自定义设置和进口的,所以我不知道哪个值将举行儿童数2.
的方式我目前的解决方案是在导入过程中的排名吧,因为我使用的是Oracle,这是很简单 - 我只需要使用rank
窗口功能。但对我来说似乎很尴尬,我觉得可以有更优雅的解决方案。我试了下查询和它的作品,但它看起来奇怪,它在更大的图形非常慢:
match (p {my_id: 1 })-->(c)
optional match (c)-->(cc)
where size([ (p)-->(c1) where c1.sort < c.sort |c1]) < 2
return p, c, cc
下面是这个查询的计划和最昂贵的部分其实是在size
表达:
非常感谢您的扩大答复,我已经将剖析计划添加到我的问题。实际上,实际的DB需要索引和标签,正如您在计划中看到的那样,而计划中最昂贵的部分实际上就是具有大小的子句。话虽如此,你的查询是非常高效的,所以我会说这是诀窍!再次感谢! –