Neo4j Cypher语言 - 根据节点数量变化遍历深度



我有一个Neo4j数据库(版本2.0.0),其中包含单词及其与其他单词的词源关系。我目前能够通过遍历这些词源来创建"词网络",使用可变深度的Cypher查询。

出于客户端的性能原因(这些网络是在JavaScript中可视化的),并且由于关系的数量从一个单词到下一个单词变化很大,我希望能够使深度遍历以节点的数量为条件。我的查询当前看起来像这样:

start a=node(id)
match p=(a)-[r:ORIGIN_OF*1..5]-(b)
where not b-->()
return nodes(p)

将深度设置为5通常会产生非常有趣的结果,但有时交付的节点太多,我的客户端可视化无法处理。我想检查,例如,sum(length(nodes(p)))和递减深度,如果结果超过一个特定的最大值。或者,当然,任何其他实现这一目标的方法。

我已经尝试在路径遍历中添加WHERE子句,但这是特定于单个路径的,并且不允许我sum()节点的总数。

提前感谢!

您想要做的不是在单个查询中相当直接。假设您在word属性上使用标签和索引,下面的查询应该可以满足您的要求。

MATCH p=(a:Word { word: "Feet" })-[r:ORIGIN_OF*1..5]-(b)
WHERE NOT (b)-->()
WITH reduce(pathArr =[], word IN nodes(p)| pathArr + word.word) AS wordArr
MATCH (words:Word)
WHERE words.word IN wordArr
WITH DISTINCT words
MATCH (origin:Word { word: "Feet" })
MATCH p=shortestPath((words)-[*]-(origin))
WITH words, length(nodes(p)) AS distance
RETURN words
ORDER BY distance 
LIMIT 100

我应该提到,这很可能不会扩展到庞大的数据集。如果有1000多个路径从你的原始单词延伸,很可能需要几秒钟才能完成。

查询基本上通过将路径中的所有不同节点收集到一个单词数组中来执行径向距离操作。然后,它测量从每个不同的单词到原始单词的最短路径距离,并按最近的距离排序,并施加结果的最大限制,例如100。

尝试一下,看看它在你的数据集中表现如何。请确保对word属性进行索引,并将Word标签应用于适用的单词节点。

我想到的是一个愚蠢的图形优化:

你需要做的是将信息添加到每个节点中,这将显示从1到5的每个深度有多少连接,即:

start a=node(id)
match (a)-[r:ORIGIN_OF*1..1]-(b)
with count(*) as cnt
set a.reach1 = cnt
...
start a=node(id)
match (a)-[r:ORIGIN_OF*5..5]-(b)
where not b-->()
with count(*) as cnt
set a.reach5 = cnt

然后,在每次运行上面的问题查询之前,检查reachX [r:ORIGIN_OF*X..X]>

运行查询

这将有一些后果-您必须在每次新项目或更新发生在您的数据库之后运行此优化,或者在每个新节点/更新节点之后,您必须将reachX参数添加到更新

最新更新