2013-03-30 88 views
2

我想從數據庫查詢數據到一個json數組中,ultimalty在javascript中產生一個強制有向圖。這是Json數組應該是什麼樣的。然而,節點可以有多個鄰接關係,或者沒有鄰接關係,我怎樣才能查詢一個json數組,其中的鄰接節在不同節點之間變化,並且能夠根據節點的鄰接數量進行調整?複雜的嵌套數組問題

Var JSON =[ 
{ 
    "adjacencies": [ 
    { 
     "nodeTo": "graphnode9", 
     "nodeFrom": "graphnode5", 
     "data": {} 
    } 
    ], 
    "data": { 
    "$color": "#416D9C", 
    "$type": "star" 
    }, 
    "id": "graphnode5", 
    "name": "graphnode5" 
}, 
]; 

或者他們可以有

Var JSON =[ 
{ 
    "adjacencies": [ 
    { 
     "nodeTo": "graphnode9", 
     "nodeFrom": "graphnode5", 
     "data": {} 
    }, 
    { 
     "nodeTo": "graphnode9", 
     "nodeFrom": "graphnode5", 
     "data": {} 
    }, 
    { 
     "nodeTo": "graphnode9", 
     "nodeFrom": "graphnode5", 
     "data": {} 
    } 
    ], 
    "data": { 
    "$color": "#416D9C", 
    "$type": "star" 
    }, 
    "id": "graphnode5", 
    "name": "graphnode5" 
}, 
]; 

或者他們不能有任何

Var JSON =[ 
{ 
    "adjacencies": [], 
    "data": { 
    "$color": "#416D9C", 
    "$type": "star" 
    }, 
    "id": "graphnode5", 
    "name": "graphnode5" 
}, 
]; 

這裏是我的嘗試,到目前爲止,然而,這只是產生一個JSON只允許一個鄰接,我如何設置一個Json查詢來調整節點的鄰接數量?而只是加載數據和ID部分一次,但允許相鄰變化?

這裏是我的數據庫結構

nodes     Relationships      
-----     ------------- 
id int(11),   id int(11), 
name varchar(35), goingto int(11), //this is the destination node from the id relation 
color varchar(7),  data varchar(0) null 
type varchar (12), Foreign key (id) references nodes(id) 
Primary key (id)  

engine = innodb  

這裏是我的嘗試是

function getjson(){ 
$db = adodbConnect(); 
$query = "SELECT nodes.*, relationships.* FROM nodes inner JOIN relationships ON nodes.id = relationships.id"; 
$result = $db -> Execute($query); 

while($row=$result->FetchRow()) 
{ 
    $id= (float)$row['id']; 
    $name = $row['name']; 
    $color1 = $row['color']; 
    $type1 = $row['type']; 
    $to= (float)$row['goingto']; 
    $thumb =$row['thumb']; //image path 

    $array[] = array(
    "adjacencies" => array(array(
    "nodeTo" => "$to", 
    "nodeFrom" => "$id", 
    "data" => array())), 
    "data" => array(
    "$"."color" => $color1, 
    "$"."type" => $type1), 
    "id" => $id, 
    "name" => "<img src='".$thumb."' height='25' width='25' alt='root'/><label>".$name."</label>"); 
} 

$json = json_encode($array); 
print "$json"; 
//return $json; 
} 
+0

你的意思是你永遠不會得到一個空的鄰接列表?如果這是問題,請使用LEFT JOIN。 – bfavaretto

+0

沒有一切正確加載,但爲每個節點加載id和數據數組一次,但保持鄰接多次,同時保持整個數組的結構。 – user1902588

+0

@ user1902588看來您已經提出了同樣的問題3次。這一個,然後[這裏](http://stackoverflow.com/questions/15608156/array-with-multiple-sizes-query-from-database-issue),也[這裏](http://stackoverflow.com /問題/ 15714467/multideminsional陣列查詢迭代-問題)。最後一個關閉了,我會推薦另一個關閉以及它沒有答案/評論等。 – Sepster

回答

2

如果你想在一個單一的查詢返回的結果,那麼你最終會與重複數據節點,在每個單獨的行中,該節點有一個獨特的鄰接關係......這很好,它就是這樣工作的。

但是因爲它位於,你不會得到節點返回,如果有該節點上沒有鄰接(因爲你使用的是INNER join。您應該使用LEFT join以包括沒有從相關鄰接表結果節點) 。

通過按節點id排序,我們明確確保所有節點及其鄰接點都顯示在一起。這可能已經發生,因爲id是你的PK,因此這種排序「自動」發生。但是ORDER BY nodes.id可以確保這種情況發生,並且讓任何人都能看清代碼。

而且,因爲你從兩個表返回的一切*,你將有列名衝突,在node.idrelationship.id。理想情況下,您應明確指定列名稱以避免出現這種情況,以便在PHP中獲得可預測的結果。

所以,你的SQL可能看起來更像:

SELECT 
    n.id as n_id, 
    n.name, 
    n.color, 
    n.type, 
    r.id as r_id, 
    r.goingto, 
    r.data 

FROM 
    nodes n 

    LEFT JOIN relationships r 
    ON n.id = r.id 

ORDER BY 
    n.id 

這將返回一個結果集,看起來像:

n_id | name | color | type | r_id | goingto | data 
------+-------+--------+-------+------+---------+----------- 
1  | node1 | red | type1 | 1 | 5  | stuff 
1  | node1 | red | type1 | 2 | 6  | morestuff 
2  | node2 | blue | type2 | 3 | 10  | whatever 
3  | node3 | green | type3 | null | null | null 
4  | node4 | orange | type4 | 4 | 20  | xxx1 
4  | node4 | orange | type4 | 5 | 21  | xxx2 
4  | node4 | orange | type4 | 6 | 22  | xxx3 

etc... 

(即該假設節點1有兩個關係,節點2有1關係,節點3沒有關係,節點4有3)。

然後,構建數組的代碼只需要迭代結果,僅噹噹前記錄的節點與前一個節點不相同時才構建新節點(即我們依靠ORDER BY node.id「聚集「一個特定節點的所有信息,按順序)。

此代碼尚未經過測試,但我認爲意圖很明確,您應該可以根據需要進行修改 - 但它基本上只是實現了上述功能。

用所有這些替換您的while循環。

$previd = -1; 
while($row=$result->FetchRow()) 
{ 
    $id= (float)$row['n_id']; // <--- note change from 'id' to 'n_id' 
    $name = $row['name']; 
    $color1 = $row['color']; 
    $type1 = $row['type']; 
    $to= (float)$row['goingto']; 
    $thumb =$row['thumb']; //image path 

    // Is this row the start of a new node?  
    if ($previd != $id) { 
     // Yes, new node. Record our new node id, for future new node checks. 
     $previd = $id; 

     // Store the previous node we've already built, now that it's complete (but only if there was a previous node!) 
     if ($previd != -1) { 
      $array.push($node); 
     } 

     // Start our new node off, ready to accept adjacencies 
     $node = array(
      "adjacencies" => array(), 
      "data" => array(
        "$"."color" => $color1, 
        "$"."type" => $type1 
       ), 
      "id" => $id, 
      "name" => "<img src='".$thumb."' height='25' width='25' alt='root'/><label>".$name."</label>"); 
    } 

    // Any adjacency for this node, on this row? 
    if ($to != null) { // <-- Not sure about this line! 
     // Yes there is, so create the new adjacency record and add it to the current node's adjacency array. 
     $node["adjacencies"].push(
      array(
       "nodeTo" => "$to", 
       "nodeFrom" => "$id", 
       "data" => array() 
      ) 
     ); 
    } 
} 

我不知道如何「不相鄰」將在$to表示 - 也就是說,如果這將是「空」或什麼。我會留給你測試,但足以說你需要反映這一行if ($to != null) { // <-- Not sure about this line!

+0

sepster你已經在這段關於sql語句,然後我的數據庫理論老師的片段中教會了我更多。我非常感謝你的幫助。 – user1902588

+0

@ user1902588我的快樂伴侶,真的很高興你覺得它有用。感謝接受,我真的很感激。 – Sepster