2016-12-25 130 views
0

我想獲得一個密碼,可以給我的路線和可用的座位來源到目的地。以下是我的圖表設置Neo4j路徑與過濾器

create (t1:Trip{id:"red"}), (t2:Trip{id:"blue"}), (a:City{id:"A"}), (b:City{id:"B"}), (c:City{id:"C"}), (d:City{id:"D"}) 
create (t1)-[:stop_at]->(a),(t1)-[:stop_at]->(b),(t1)-[:stop_at]->(c),(t1)-[:stop_at]->(d),(t2)-[:stop_at]->(a),(t2)-[:stop_at]->(b),(t2)-[:stop_at]->(c),(t2)-[:stop_at]->(d) 
create (a)-[:red]->(b),(b)-[:red]->(c),(c)-[:red]->(d) create (a)-[:blue]->(b),(b)-[:blue]->(c),(c)-[:blue]->(d) 
create (b)-[:red_01{seat:40}]->(c),(c)-[:red_01{seat:40}]->(d) 

我有兩個「旅行」,「紅色」和「藍色」。使用「旅行」ID在節點之間創建的關係(停止)只是抽象鏈接。我想尋找停在「A」和「D」的旅行,我用下面的查詢返回旅行「紅色」和「藍色」。

match (t:Trip)-[:stop_at]->(c:City) where c.id = "A" or c.id = "D" return distinct t.id 

然後,我想要得到的路徑,我正在使用以下查詢。

match (t:Trip)-[:stop_at]->(c:City) where c.id = "A" or c.id = "D" with distinct t.id as id 
match (source:City{id:"A"})-[rel*]->(dest:City{id:"D"}) where all(item in rel where starts with id) return rel 

它返回結合了每條可能路徑的36行。例如:

[(A)-[:blue]->(B), (B)-[:blue]->(C), (C)-[:blue]->(D)] 
[(A)-[:red]->(B), (B)-[:red]->(C), (C)-[:red]->(D)] 
[(A)-[:red]->(B), (B)-[:red]->(C), (C)-[:red_01 {seat:40}]->(D)] 
[(A)-[:red]->(B), (B)-[:red_01 {seat:40}]->(C), (C)-[:red]->(D)] 
[(A)-[:red]->(B), (B)-[:red_01 {seat:40}]->(C), (C)-[:red_01 {seat:40}]->(D)] 

我想獲得情況如下:

[(A)-[:blue]->(B), (B)-[:blue]->(C), (C)-[:blue]->(D)] 
[(A)-[:red]->(B), (B)-[:red_01 {seat:40}]->(C), (C)-[:red_01 {seat:40}]->(D)] 

後綴「_01」是指有兩個站之間的日期/時間之旅出售。對於所有的「紅色」旅行,我希望只獲得包含最大銷售額的路徑。如果我們看一下上面的結果,它將是第5行。「藍色」之旅當天沒有任何銷售,所以我們將保留結果。

這裏是neo4j控制檯供您參考。非常感謝您的幫助。

http://console.neo4j.org/?id=2sho3j

瑞安

+0

好問題 - 感謝提供樣本數據集,並詳細描述你的問題。但是,您的第三個查詢片段不會編譯:'where all(rel in以id開頭的項目)'缺少某些內容。正確的表達應該像'WHERE ... STARTS WITH ...'一樣閱讀 –

回答

0

這個查詢是朝着回答您的解決方案了一步:

match (t:Trip)-[:stop_at]->(c:City) 
where c.id = "A" or c.id = "D" 
with distinct t.id as id 
match (source:City{id:"A"})-[rel*]->(dest:City{id:"D"}) 
where all(item in rel where type(item) starts with id) 
return rel, extract(r in rel | type(r)) as reltypes 

它返回:

╒════════════════════════════╤═════════════════════╕ 
│rel       │reltypes    │ 
╞════════════════════════════╪═════════════════════╡ 
│[{}, {}, {}]    │[blue, blue, blue] │ 
├────────────────────────────┼─────────────────────┤ 
│[{}, {seat: 40}, {}]  │[red, red_01, red] │ 
├────────────────────────────┼─────────────────────┤ 
│[{}, {seat: 40}, {seat: 40}]│[red, red_01, red_01]│ 
├────────────────────────────┼─────────────────────┤ 
│[{}, {}, {}]    │[red, red, red]  │ 
├────────────────────────────┼─────────────────────┤ 
│[{}, {}, {seat: 40}]  │[red, red, red_01] │ 
└────────────────────────────┴─────────────────────┘ 

不過,我認爲我們應該提高數據模型第一:

  • 在關係類型中使用後綴來表示可能經常發生變化的信息(這裏用於指示是否有銷售)是一個壞主意。我建議使用關係屬性,例如sale: true/false或將銷售日期添加爲列表(存儲日期可能非常棘手:使用時間戳,字符串,APOC date/time support - 無論哪種情況最適合您的用例)。
  • 您也可以考慮將路線的顏色存儲爲屬性,例如, (a)-[:ROUTE {colour: 'red'}]->(b)ROUTE應儘可能描述,例如TRAIN或可能CONNECTED_BY_TRAIN)。

所以,回到你的問題(使用原來的數據模型):

reduce

match (t:Trip)-[:stop_at]->(c:City) 
where c.id = "A" or c.id = "D" 
with distinct t.id as id 
match (source:City{id:"A"})-[rel*]->(dest:City{id:"D"}) 
where all(item in rel where type(item) starts with id) 
return rel, extract(r in rel | type(r)) AS reltypes, 
    reduce(
    noSales = 0, 
    item IN rel | noSales + 
     case type(item) ends with '_01' 
     when true then 1 
     else 0 
     end) AS noSales 

或者簡單一點,你可以使用各種方法計算的特定路徑上銷售寬度filterlength

match (t:Trip)-[:stop_at]->(c:City) 
where c.id = "A" or c.id = "D" 
with distinct t.id as id 
match (source:City{id:"A"})-[rel*]->(dest:City{id:"D"}) 
where all(item in rel where type(item) starts with id) 
return rel, extract(r in rel | type(r)) AS reltypes, 
    length(filter(item in rel where type(item) ends with '_01')) AS noSales 

兩個返回以下RESU LT:

╒════════════════════════════╤═════════════════════╤═══════╕ 
│rel       │reltypes    │noSales│ 
╞════════════════════════════╪═════════════════════╪═══════╡ 
│[{}, {}, {}]    │[blue, blue, blue] │0  │ 
├────────────────────────────┼─────────────────────┼───────┤ 
│[{}, {seat: 40}, {}]  │[red, red_01, red] │1  │ 
├────────────────────────────┼─────────────────────┼───────┤ 
│[{}, {seat: 40}, {seat: 40}]│[red, red_01, red_01]│2  │ 
├────────────────────────────┼─────────────────────┼───────┤ 
│[{}, {}, {}]    │[red, red, red]  │0  │ 
├────────────────────────────┼─────────────────────┼───────┤ 
│[{}, {}, {seat: 40}]  │[red, red, red_01] │1  │ 
└────────────────────────────┴─────────────────────┴───────┘ 

爲了獲得最大的銷售,你只需要排序,並獲得最高的結果:

order by noSales desc 
limit 1