搜索大量节点并按路径排序

时间:2014-12-09 23:52:21

标签: performance neo4j

我有一个包含某种实体节点的数据库,其中一个是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)。

是否存在某种方式以最佳性能执行此类查询?

谢谢

1 个答案:

答案 0 :(得分:2)

[被修改]

您的Cypher逻辑似乎存在很多问题。例如:

  1. 以下两个条款无缘无故地做了很多工作。您将所有匹配的用户节点放在一个集合中,然后立即将新集合重新分成单独的行。否则不会使用nodes集合。

     WITH COLLECT(a) AS nodes
     UNWIND nodes AS node
    
  2. 您使用[*2..2]强制p仅包含具有固定长度的路径,然后计算p的长度(如果它不是NULL) - 当您已经知道长度必须是什么。

  3. 您不会阻止同一节点在结果中多次显示。这是因为您的OPTIONAL MATCH结果节点也将显示为MATCH结果节点,并且用户7119046也可以使用多个路径与同一节点相关联。

  4. [答案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