繁体   English   中英

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

[英]Limit by each node, rather than whole query

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

我目前的询问是:

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

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

这是普通用户可能看到的(简化):

在此输入图像描述

如果找到的第一个节点有很多照片,则会返回以下内容:

在此输入图像描述

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

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

您可以通过限制路径长度来使用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;
    }
}

我认为您需要以下内容:

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

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

您可以手动构建此查询:

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使用简单的连接来收集此结构。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM