我有一个包含某种实体节点的数据库,其中一个是User,每个User都有一个名为idcountry的属性,以表示用户的国家,我创建了很多我的用户之间的关系,但我是寻找对他们提出一些建议,其中一个建议是基于同一用户所在国家的所有用户,但我想把列表的顶部放在二年级的用户,我写了这个查询:< / p>
MATCH (a:`User`)
WHERE a.idcountry = 115
WITH COLLECT(a) AS nodes
UNWIND nodes AS node
OPTIONAL MATCH p = (me:`Usuario` {iduser: 7119046})-[*2..2]-(node)
RETURN node,
CASE WHEN p IS NULL THEN 0 ELSE MIN(LENGTH(p)) END AS close_to
ORDER BY close_to DESC
LIMIT 25
问题是我在国家115中有大约11,000,000个用户(此属性有索引),并且此查询需要44759毫秒才能运行,我猜这个查询正在扫描这个国家/地区的所有节点然后它正在进行操作以确定等级(close_to)。
是否存在某种方式以最佳性能执行此类查询?
谢谢
答案 0 :(得分:2)
[被修改]
您的Cypher逻辑似乎存在很多问题。例如:
以下两个条款无缘无故地做了很多工作。您将所有匹配的用户节点放在一个集合中,然后立即将新集合重新分成单独的行。否则不会使用nodes
集合。
WITH COLLECT(a) AS nodes
UNWIND nodes AS node
您使用[*2..2]
强制p
仅包含具有固定长度的路径,然后计算p
的长度(如果它不是NULL) - 当您已经知道长度必须是什么。
您不会阻止同一节点在结果中多次显示。这是因为您的OPTIONAL MATCH
结果节点也将显示为MATCH
结果节点,并且用户7119046也可以使用多个路径与同一节点相关联。
[答案1]
如果您只是寻找通过减少路径长度排序的最多25个链接到您的节点,通过减少路径长度排序,以下查询应该适合您。我假设:Usuario(iduser)
和:User(idcountry)
都被编入索引。
MATCH p = (me:`Usuario` {iduser: 7119046})-[*..2]-(node:User {idcountry: 115})
RETURN DISTINCT node
ORDER BY LENGTH(p) DESC
LIMIT 25
[答案2] 如果您要查找最多25个节点,这些节点与您链接的距离恰好为2步,或者没有链接到您正好2步的距离,前者在结果中首先显示,则以下查询应该可以正常工作为了你。与上述相同的索引假设适用。
注意:此查询实际上最多会返回50行,但您应该忽略前25行之后的任何内容。此外,同一节点仍然可以在结果中出现两次(一次来自第一次MATCH,一次来自第二次)。
MATCH (me:`Usuario` {iduser: 7119046})-[*2..2]-(n:User {idcountry: 115})
RETURN DISTINCT node
LIMIT 25
UNION
MATCH (me:`Usuario` {iduser: 7119046}), (node:User {idcountry: 115})
WHERE NOT (me)-[*2..2]-(node)
RETURN DISTINCT node
LIMIT 25