2013-03-30 90 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