2016-08-15 39 views
0

标题:我如何动态地命名一个集合?如何动态命名集合?

伪代码:collect(n) AS :Label

这样做的主要目的是在API服务器(节点应用)的属性的容易阅读。

放牧,例如:在JSON

MATCH (user:User)--(n) 
WHERE n:Movie OR n:Actor 
RETURN user, 
CASE 
    WHEN n:Movie THEN "movies" 
    WHEN n:Actor THEN "actors" 
END as type, collect(n) as :type 



预期输出:

[{ 
    "user": { 
     .... 
    }, 


    "movies": [ 
     { 
      "_id": 1987, 
      "labels": [ 
       "Movie" 
      ], 
      "properties": { 
       .... 
      } 
     } 
    ], 

    "actors:" [ .... ] 
}] 

我已经得到最接近的是:

[{ 
    "user": { 
     .... 
    }, 

    "type": "movies", 
    "collect(n)": [ 
     { 
      "_id": 1987, 
      "labels": [ 
       "Movie" 
      ], 
      "properties": { 
       .... 
      } 
     } 
    ] 
}] 

我们的目标是能够轻松读取JSON结果如下所示:

neo4j.cypher.query(statement, function(err, results) { 
    for result of results 
    var user = result.user 
    var movies = result.movies 
} 

编辑: 我在不能正确地命名数据库的语义对于任何混乱表示歉意。

+1

您可以在输出的预期增加时,有两个相关的电影和演员?你将同时在同一行中得到两个... – InverseFalcon

+0

我不知道我理解你。每当我在一个工作数据集上尝试这个时,collect(n)设法将两个集合分成两个不同的数组,这就是为什么我需要动态地命名该数组集合,而不是返回数据中的collect(n)。 我正在寻找的是一种方式来做var movies = response.movi​​es等。 –

+0

我已经更新了示例,希望能够澄清预期的输出。 –

回答

2

我不知道它是否够只是输出的用户和他们既是演员名单,并电影,而不是试图做一个更复杂的手段来匹配和结合两者。

MATCH (user:User) 
OPTIONAL MATCH (user)--(m:Movie) 
OPTIONAL MATCH (user)--(a:Actor) 
RETURN user, COLLECT(m) as movies, COLLECT(a) as actors 
+1

这个写入的请求将无法返回任何内容,除非用户与电影和演员相关。 – cybersam

+0

@cybersam感谢您的支持!已更新为使用可选匹配项。 – InverseFalcon

+0

这正是我所寻找的。非常感谢你! –

2

此查询应该返回各自User和他/她相关的电影和演员(在单独的集合):

MATCH (user:User)--(n) 
WHERE n:Movie OR n:Actor 
RETURN user, 
    REDUCE(s = {movies:[], actors:[]}, x IN COLLECT(n) | 
    CASE WHEN x:Movie 
     THEN {movies: s.movies + x, actors: s.actors} 
     ELSE {movies: s.movies, actors: s.actors + x} 
    END) AS types; 
+0

谢谢你提供你的答案。虽然这不是我要找的。我基本上只是想通过动态属性名称(标签)对收集集进行排序 –

+0

您想按标签排序吗?你能澄清这是什么意思吗? – cybersam

+0

请参阅问题更新。 –

1

至于动态解决你的问题,一个将连接到你的用户的任何节点的工作,有几个选择,但我不相信你可以得到的列名是动态像这样,甚至返回的集合的名称,但我们可以将它们与类型关联起来。

MATCH (user:User)--(n) 
WITH user, LABELS(n) as type, COLLECT(n) as nodes 
WITH user, {type:type, nodes:nodes} as connectedNodes 
RETURN user, COLLECT(connectedNodes) as connectedNodes 

或者,如果你喜欢与多个行的工作,每个每个节点类型一行:

MATCH (user:User)--(n) 
WITH user, LABELS(n) as type, COLLECT(n) as collection 
RETURN user, {type:type, data:collection} as connectedNodes 

注意LABELS(n)返回标签的列表,因为节点可以是多重标记。如果确保每个感兴趣的节点都有一个标签,那么可以使用列表的第一个元素,而不是列表本身。改用LABELS(n)[0]

0

可以动态排序标签节点,然后通过转换为地图apoc library

WITH ['Actor','Movie'] as LBS 
// What are the nodes we need: 
MATCH (U:User)--(N) WHERE size(filter(l in labels(N) WHERE l in LBS))>0 
WITH U, LBS, N, labels(N) as nls 
UNWIND nls as nl 
    // Combine the nodes on their labels: 
    WITH U, LBS, N, nl WHERE nl in LBS 
    WITH U, nl, collect(N) as RELS 
    WITH U, collect([nl, RELS]) as pairs 
    // Convert pairs "label - values" to the map: 
    CALL apoc.map.fromPairs(pairs) YIELD value 
RETURN U as user, value