2016-08-15 73 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