使用PHP操作Neo4j的例子

Neo4j是目前最热门的图数据库之一,图数据库以计算机图结构为基础,擅长处理复杂的数据关系。比如我们常见的社交网络中的人与人的关系图。下面是一个用使用PHP客户端通过Neo4j的REST接口进行数据操作的例子。

原文链接:Neo4j for PHP

如果我们有如下一个电影角色表:

> desc roles;
+-------------+--------------+------+-----+---------+----------------+
| Field       | Type         | Null | Key | Default | Extra          |
+-------------+--------------+------+-----+---------+----------------+
| id          | int(11)      | NO   | PRI | NULL    | auto_increment |
| actor_name  | varchar(100) | YES  |     | NULL    |                |
| role_name   | varchar(100) | YES  |     | NULL    |                |
| movie_title | varchar(100) | YES  |     | NULL    |                |
+-------------+--------------+------+-----+---------+----------------+

> SELECT actor_name, role_name FROM roles WHERE movie_title IN (SELECT DISTINCT movie_title FROM roles WHERE actor_name='Kevin Bacon')

我们需要用上面的复杂SQL语句才能获取到和Kevin Bacon一起演出过的演员名单。

如果我们需要获取一个与和Kevin Bacon一起演出过的人一起演出过的演员名单(真拗口)就更麻烦了,再试想多一层,与(与(与Kevin Bacon一起演出过的演员)一起演出过的演员)一演出过的演员。那几乎是不可完成的任务了。

其实角色关系图就是如下的图结构,而这种应用其实正好是图类型数据库的典型应用场景,蓝色框表示演员,黄色框表示电影

下面我们直接使用Neo4j的PHP客户端来构建图谱:

$client = new Client(new Transport('localhost', 7474));
//构建演员节点
$keanu = new Node($client);
$keanu->setProperty('name', 'Keanu Reeves')->save();
$laurence = new Node($client);
$laurence->setProperty('name', 'Laurence Fishburne')->save();
$jennifer = new Node($client);
$jennifer->setProperty('name', 'Jennifer Connelly')->save();
$kevin = new Node($client);
$kevin->setProperty('name', 'Kevin Bacon')->save();
//构建电影节点
$matrix = new Node($client);
$matrix->setProperty('title', 'The Matrix')->save();
$higherLearning = new Node($client);
$higherLearning->setProperty('title', 'Higher Learning')->save();
$mysticRiver = new Node($client);
$mysticRiver->setProperty('title', 'Mystic River')->save();
//建立关联关系
$keanu->relateTo($matrix, 'IN')->save();
$laurence->relateTo($matrix, 'IN')->save();

$laurence->relateTo($higherLearning, 'IN')->save();
$jennifer->relateTo($higherLearning, 'IN')->save();

$laurence->relateTo($mysticRiver, 'IN')->save();
$kevin->relateTo($mysticRiver, 'IN')->save();

然后我们就能够在已经建立好的图结构上进行数据查询了。第一个查询是查找所有与Kevin Bacon距离为12的其它人(演员与演员间的距离只能是2的倍数,因为中间隔着电影)。

$path = $keanu->findPathsTo($kevin)
    ->setMaxDepth(12)
    ->getSinglePath();

foreach ($path as $i => $node) {
    if ($i % 2 == 0) {
        echo $node->getProperty('name');
        if ($i+1 != count($path)) {
            echo " was in\n";
        }
    } else {
        echo "\t" . $node->getProperty('title') . " with\n";
    }
}

你也可以用下面的语句查询所有与Laurence Fishburne相关的电影:

echo $laurence->getProperty('name') . " was in:\n";
$relationships = $laurence->getRelationships('IN');
foreach ($relationships as $relationship) {
    $movie = $relationship->getEndNode();
    echo "\t" . $movie->getProperty('title') . "\n";
}

anyShare分享此文章的同学,将有机会送我iphone5!
          

无觅相关文章插件,快速提升流量

分类 Neo4j · tag , , ,