由每个节点限制,而不是整个查询

时间:2017-02-15 10:52:57

标签: javascript node.js neo4j cypher

我有大量的用户和照片,它们之间有三种可能的关系(以后可能会添加更多)。这些关系为POSTED_BYAPPEARS_INMENTIONED_IN。给定一个特定用户,我想要一个查询,使其网络返回n跳跃。例如,这应该包括他们发布的照片​​,他们出现或被提及的照片,以及发布这些照片的帐户。

我目前的询问是:

MATCH (root:account { username: {username} })-[r*1..4]-(u)
RETURN *
LIMIT 50

这个问题是限制是根据总行数完成的。这导致在具有大量子节点时仅返回一个1级节点。这是对问题的更直观的解释。

这是普通用户的看法(简化):

enter image description here

如果找到的第一个节点有很多照片,这就是返回的内容:

enter image description here

由于用户拥有大量媒体,因此无需显示其网络的准确表示即可达到极限。相反,我希望我的查询将每个节点限制为最多n个子节点。

从我在这里阅读的几个答案来看,COLLECT看起来应该是可能的,但我找不到任何例子。

3 个答案:

答案 0 :(得分:0)

您可以通过限制路径长度来使用cypher执行此操作:

MATCH path=(root:account { username: {username} })-[r*1..4]-(u)
WITH COLLECT(path) as paths
RETURN filter(x in paths WHERE length(x)<50)

您可以在使用Neo4j Traversal API时执行此操作。在求值程序中,您可以检查路径的长度,并在路径超过所需长度时进行修剪。

import org.neo4j.graphdb.Direction;
import org.neo4j.graphdb.Path;
import org.neo4j.graphdb.traversal.Evaluation;
import org.neo4j.graphdb.traversal.Evaluator;

public class MyEvaluator implements Evaluator{

    @Override
    public Evaluation evaluate(Path path) {
        if(path.length()>=50)
        {           
            return Evaluation.INCLUDE_AND_PRUNE;
        }

        return Evaluation.INCLUDE_AND_CONTINUE;
    }
}

答案 1 :(得分:0)

我认为您需要以下内容:

 MATCH (root:account { username: {username} })-[]-> (child1)-[r*1..4]-(u)
 RETURN child1, collect(u)
 LIMIT 50

这将返回最多50行 每行将有两列。第一列是child1s,第二列是这个孩子的'Us'

答案 2 :(得分:0)

您可以手动构建此查询:

MATCH (root:account { username: {username} }) 
WITH {ids: [root], rels: []} as graph

UNWIND graph.ids as N  
  MATCH (N)-[r]->(C) WHERE NOT C IN graph.ids
  WITH graph, C, r LIMIT 50
  WITH graph, collect(C) as ids, collect(r) as rels
  WITH {ids: ids + graph.ids, rels: graph.rels + rels} as graph

UNWIND graph.ids as N  
  MATCH (N)-[r]->(C) WHERE NOT C IN graph.ids
  WITH graph, C, r LIMIT 50
  WITH graph, collect(C) as ids, collect(r) as rels
  WITH {ids: ids + graph.ids, rels: graph.rels + rels} as graph

UNWIND graph.ids as N  
  MATCH (N)-[r]->(C) WHERE NOT C IN graph.ids
  WITH graph, C, r LIMIT 50
  WITH graph, collect(C) as ids, collect(r) as rels
  WITH {ids: ids + graph.ids, rels: graph.rels + rels} as graph

UNWIND graph.ids as N  
  MATCH (N)-[r]->(C) WHERE NOT C IN graph.ids
  WITH graph, C, r LIMIT 50
  WITH graph, collect(C) as ids, collect(r) as rels
  WITH {ids: ids + graph.ids, rels: graph.rels + rels} as graph

RETURN graph.rels

当然,在大跳跃的情况下,可以通过javascript使用简单的连接来收集此结构。