我有一个Neo4j数据库(版本2.0.0),其中包含单词及其与其他单词的词源关系。我目前能够创建" word networks"通过遍历这些词源,使用可变深度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()
节点总数。
提前致谢!
答案 0 :(得分:0)
在单个查询中,您要做的事情并不是那么简单。假设您在单词属性上使用标签和索引,以下查询应该执行您想要的操作。
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
标签应用于适用的单词节点。
答案 1 :(得分:0)
我想到的是图表的愚蠢优化:
您需要做的是向每个节点添加一个信息,该信息将显示每个深度从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< you_wished_results并使用[r:ORIGIN_OF*X..X]
这会产生一些后果 - 要么在每次新项目或更新发生在数据库之后都需要运行此优化,或者在每个新节点/更新节点之后必须将reachX
参数添加到更新中