简体   繁体   English

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

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

I have a load of users and photos, with three possible relationships between them (with potentially more added later). 我有大量的用户和照片,它们之间有三种可能的关系(可能会在以后添加更多)。 These relationships are POSTED_BY , APPEARS_IN and MENTIONED_IN . 这些关系POSTED_BYAPPEARS_INMENTIONED_IN Given a particular user, I want a query which returns their network up to n jumps away. 给定一个特定的用户,我想要一个查询,它返回他们的网络n跳。 For example, this should include photos they've posted, photos they appear in or are mentioned in, along with the accounts which posted those photos. 例如,这应该包括他们发布的照片​​,他们出现或被提及的照片,以及发布这些照片的帐户。

My query at the moment is: 我目前的询问是:

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

The issue with this is that the limit is done based on the total rows. 这个问题是限制是基于总行完成的。 This results in only returning one level 1 node when it has lots of subnodes. 这导致在具有大量子节点时仅返回一个1级节点。 Here is a more visual explanation of the problem. 这是对问题的更直观的解释。

This is what it might look with an ordinary user (simplified): 这是普通用户可能看到的(简化):

在此输入图像描述

If the first node found has a lot of photos, this is what gets returned: 如果找到的第一个节点有很多照片,则会返回以下内容:

在此输入图像描述

As the user has a lot of media, it hits the limit without showing an accurate representation of their network. 由于用户拥有大量媒体,因此无需显示其网络的准确表示即可达到极限。 Instead, I'd like my query to limit each node to a maximum of n subnodes. 相反,我希望我的查询将每个节点限制为最多n个子节点。

From a couple of answers I've read on here, it looks like it should be possible with COLLECT , however I can't really find any examples. 从我在这里读到的几个答案来看,它看起来应该可以用COLLECT ,但是我找不到任何例子。

You can do this with cypher by limiting path length: 您可以通过限制路径长度来使用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)

You can do this while using Neo4j Traversal API. 您可以在使用Neo4j Traversal API时执行此操作。 In evaluator, you can have a check on a length of the path and prune when path is more than the desired length. 在求值程序中,您可以检查路径的长度,并在路径超过所需长度时进行修剪。

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;
    }
}

I think you need something like the following: 我认为您需要以下内容:

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

this will return up to 50 rows each row will have two columns. 这将返回最多50行,每行将有两列。 The first column will be child1s and the second column will have the 'Us' of this child 第一列是child1s,第二列是这个孩子的'Us'

You can construct this query by hand: 您可以手动构建此查询:

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

Of course, this structure can be gathered using a simple concatenation by javascript in the event of a large jumps. 当然,在大跳转的情况下,可以通过javascript使用简单的连接来收集此结构。

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

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