2

我想将数据库中的数据查询到一个 json 数组中,该数组最终会在 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;
}
4

1 回答 1

2

如果您想在单个查询中返回结果,那么您最终会得到节点的重复数据,在与该节点有不同邻接关系的每个单独的行中......这很好,这就是它的工作原理。

但是,如果该节点上没有邻接关系,则不会返回节点(因为您使用的是INNER join. 您应该使用 aLEFT join来包含相关邻接表中没有结果的节点)。

通过按节点排序id,我们明确地确保所有节点及其邻接出现分组在一起。这可能已经发生了,因为id是您的 pk,因此排序是以“自动”方式发生的。但是 anORDER BY nodes.id可以确保发生这种情况,并使任何查看代码的人都清楚您的意图。

此外,因为您*要从两个表中返回所有内容,所以您将在node.id和上发生列名冲突relationship.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- 即这将是“null”还是什么。我会把它留给你测试,但我只想说你需要在行中反映这一点if ($to != null) { // <-- Not sure about this line!

于 2013-03-30T04:21:58.437 回答