2015-12-02 36 views
1

我正在嘗試執行select語句來通過它們之間的連接強制執行結果集。通過在select語句中按順序求和邊的屬性

CREATE CLASS Entity EXTENDS V; 
CREATE CLASS isConnectedTo EXTENDS E; 

CREATE PROPERTY isConnectedTo.strength INTEGER; 

'isConnectedTo'邊緣涉及實體到另一個實體

棘手的部分是我具有相同的實體之間的雙連接爲這樣:

CREATE VERTEX Entity SET name = "John"; 
CREATE VERTEX Entity SET name = "Mike"; 
CREATE VERTEX Entity SET name = "Susan"; 

CREATE EDGE isConnectedTo FROM (SELECT FROM Entity WHERE name = "Mike") TO (SELECT FROM Entity WHERE name = "John") SET strength = 3; 
CREATE EDGE isConnectedTo FROM (SELECT FROM Entity WHERE name = "Mike") TO (SELECT FROM Entity WHERE name = "Susan") SET strength = 4; 
CREATE EDGE isConnectedTo FROM (SELECT FROM Entity WHERE name = "John") TO (SELECT FROM Entity WHERE name = "Mike") SET strength = 2; 

所以Mike連接到John也與他連接。另外邁克連接到蘇珊

在這種情況下,如果我是運行在邁克我所需的查詢,它應該返回:

  1. 約翰
  2. 蘇珊

通過這個訂單,因爲實力的總和邁克和約翰之間是3 + 2 = 5和邁克和蘇珊之間只有。

我已經遍歷了許多可能的查詢無濟於事,但我似乎無法弄清爲什麼最後一個拒絕工作。

LET $main = SELECT FROM Entity WHERE name = "John"; 
LET $vset = SELECT expand(in('isConnectedTo')) FROM $main; 
SELECT @rid, eval('$ei.strength + $eo.strength') as total_strength FROM $vset 
    LET $ei = (SELECT expand(inE('isConnectedTo')) FROM $current WHERE [email protected] IN out), 
    LET $eo = (SELECT expand(outE('isConnectedTo')) FROM $current WHERE [email protected] IN in) 
ORDER BY total_strength DESC; 

注:我已經拿到了實體名稱與哈希字典和索引‘isConnectedTo’邊緣與實體之間唯一的聯繫(因此他們不能在同一方向重複)

EDIT被索引:想要嘗試Lvca的答案,這需要一些準備工作。但我感覺很好!

所有其他試驗我做或從其他的答案在這裏幫助導致> = 2分鐘... :(

回答

2

我想提出你的域的小變化。不要創建2個邊的情況下,兩個人連接,但使用相同的邊緣與2個屬性。

CREATE CLASS Entity EXTENDS V; 
CREATE CLASS isConnectedTo EXTENDS E; 
CREATE PROPERTY isConnectedTo.strengthOut INTEGER; 
CREATE PROPERTY isConnectedTo.strengthIn INTEGER; 

CREATE VERTEX Entity SET name = "John"; 
CREATE VERTEX Entity SET name = "Mike"; 
CREATE VERTEX Entity SET name = "Susan"; 

CREATE EDGE isConnectedTo FROM (SELECT FROM Entity WHERE name = "Mike") TO (SELECT FROM Entity WHERE name = "John") SET strengthOut = 3, strengthIn = 2; 
CREATE EDGE isConnectedTo FROM (SELECT FROM Entity WHERE name = "Mike") TO (SELECT FROM Entity WHERE name = "Susan") SET strengthOut = 4; 

在這個就是你有較少的邊緣,你可以使用這個超快速查詢:

SELECT out.name as name1, in.name as name2, eval('strengthOut + strengthIn') as strength 
FROM (
    SELECT expand(bothE('isConnectedTo')) FROM Entity WHERE name = "Mike" 
) ORDER BY strength 

注:請記住,創建Entity.name索引用來加快內部查詢。

+0

謝謝Lvca!以前沒有想過這個!儘快嘗試!不過,我必須更改填充實體的腳本並重新獲取它們。用我在〜38000個實體下面指定的集合去試試這個,然後在它工作的很好的時候把它擴展到數百萬! ;) – GNSPS

+0

這個工程很棒!最後!但是,如果沒有** expand()**邊緣,它似乎無法工作......你知道爲什麼嗎,Lvca? – GNSPS

+0

你說得對,沒有展開子查詢只返回1號文件以內部集合。我改變了我的答案,包括expand()。 – Lvca

1

的查詢時間試試這個查詢

select expand(rid) from (select @rid,sum($a[0].sum,$b[0].sum) as sum from Entity 
let $a= (select sum(strength) as sum from isConnectedTo where in.name="Mike" and out.name=$parent.current.name), 
$b= (select sum(strength) as sum from isConnectedTo where out.name="Mike" and in.name=$parent.current.name) 
where name<>"Mike" order by sum desc) 
+0

非常感謝您的回答!這一次的作品! 然而,這正在採取大量的時間由於正在搜索每一個實體,然後根據在where子句中排除。也許有一種從「邁克」開始並且不必遍歷所有實體的方法? – GNSPS

+0

嘗試此查詢:選擇從擴大(myRid)(選擇myRid,總和(強度)從(選擇Expand($ C) 設$ A =(選擇了@擺脫作爲myRid,從強度(選擇Expand(INE(」。 isConnectedTo 「從實體)),其中name =」 邁克 「)), \t $ b =(選擇@擺脫作爲myRid,從強度(選擇Expand(歐特(」 isConnectedTo 「從實體)),其中name =」 邁克」 )), \t $ C = unionAll($ A,$ b) )組由myRid爲了通過總和DESC) –

1

嘗試此查詢:

select expand($a.rid) from (select from Entity where name="Mike") 
let $a=(select @rid,sum(bothE().strength) as sum from Entity where both('isConnectedTo').name contains $parent.current.name group by name order by sum desc) 
+0

謝謝MICHELA!這稍微快一點。 然而,對於一小組約38000個實體,它仍需要122秒。 注意:我計劃擁有一組數量爲數百萬的實體。 〜1m-5m – GNSPS