我们从2011年坚守至今,只想做存粹的技术论坛。  由于网站在外面,点击附件后要很长世间才弹出下载,请耐心等待,勿重复点击不要用Edge和IE浏览器下载,否则提示不安全下载不了

 找回密码
 立即注册
搜索
查看: 434|回复: 0

Neo4j3.0存储过程

[复制链接]

该用户从未签到

139

主题

157

回帖

102

积分

二级逆天

积分
102

社区居民忠实会员社区劳模原创达人终身成就奖

QQ
发表于 2016-3-14 06:27:24 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区

您需要 登录 才可以下载或查看,没有账号?立即注册

×
Neo4j 3.0 存储过程
oschina    10天前
Neo4j 3.0 提供一个新的功能“存储过程”,该功能并不是Neo4j-Server的扩展,而是可以直接运行的。

在写这篇文章的时候,只能通过预备好的语句去执行

1
CALL package.procedure(params)
但是接下来他会被完全集成到Cypher语句当中。这样我梦就可以通过CALL这个语句或者将它转换成方法表达式(这只是个人喜好)。

现在,“存储过程”只能使用Java(或者其他JVM语言)。你可能获说,“WTF  。。。java”, 其实java也没有那么一无是处。

一开始,在建立,编码,编译一个存储过程并不会花费太多的精力,只需要下载Neo4j 3.0, 3.0.0-M04 milestone或者最新的版本,同时JDK,Gradle或者Maven也需要安装。

我们可以直接使用Jake Hansson写好的一个模板neo4j-examples,这样可以更快的开始我们的第一个练习。

我们举一个简单的例子(GitHub Repository),你需要说明一下org.neo4j:neo4j:3.0.0[-M04]可以得到的取值范围,来获得必需的注释,然后Neo4j API才能讨论数据库。

1
<dependency>
2
  <groupId>org.neo4j</groupId>
3
  <artifactId>neo4j</artifactId>
4
  <version>${neo4j.version}</version>
5
  <scope>provided</scope>
6
</dependency>




Gradle 如下

1
project.ext {
2
    neo4j_version = ""
3
}
4
dependencies {
5
compile group: "org.neo4j", name:"neo4j", version:project.neo4j_version
6
testCompile group: "org.neo4j", name:"neo4j-kernel", version:project.neo4j_version, classifier:"tests"
7
testCompile group: "org.neo4j", name:"neo4j-io", version:project.neo4j_version, classifier:"tests"
8
testCompile group: "junit", name:"junit", version:4.12
9
}




如果你想写一些其他的程序,你只需要重新建立一个文件夹和新的类。

需要注意的是包和方法的名字变成了存储过程的名字(并不是类的名字)。

在我们的例子中,我们将写一个简单的存储过程来计算某个标签的最大和最小度数。

通过@Context标注可以讲Neo4j的 GraphDatabaseService 实例注入到你的类中。因为存储过程是无状态的,所以声明非注入非静态的字段是不允许的。

在我们的例子中,存储过程将命名为stats.degree,以CALL stats.degree('User')的形式进行调用。

01
package stats;
02

03
public class GraphStatistics {
04

05
    @Context private GraphDatabaseService db;
06

07
    // Result class
08
    public static class Degree {
09
        public String label;
10
        // note, that "int" values are not supported
11
        public long count, max, min = Long.MAX_VALUE;
12

13
        // method to consume a degree and compute min, max, count
14
        private void add(long degree) {
15
          if (degree < min) min = degree;
16
          if (degree > max) max = degree;
17
          count ++;
18
        }
19
    }
20

21
    @Procedure
22
    public Stream<Degree> degree(String label) {
23
        // create holder class for results
24
        Degree degree = new Degree(label);
25
        // iterate over all nodes with label
26
        try (ResourceIterator it = db.findNodes(Label.label(label))) {
27
            while (it.hasNext()) {
28
               // submit degree to holder for consumption (i.e. max, min, count)
29
               d.add(it.next().getDegree());
30
            }
31
        }
32
        // we only return a "Stream" of a single element in this case.
33
        return Stream.of(degree);
34
    }
35
}




如果你要快速的测试这个存储过程,又不想启动一个进程内服务端再连接上(比如,存储过程模板中演示的通过新的二进制的通信协议),你可以使用Neo4j测试工具集提供的Java API。



现在,我们可以写一个单元测试来测试下我们刚写的酷炫的存储过程。

01
package stats;
02

03
class GraphStatisticsTest {
04
    @Test public void testDegree() {
05
        // given Alice knowing Bob and Charlie and Dan knowing no-one
06
        db.execute("CREATE (alice:User)-[:KNOWS]->(bob:User),(alice)-[:KNOWS]->(charlie:User),(dan:User)").close();
07

08
        // when retrieving the degree of the User label
09
        Result res = db.execute("CALL stats.degree('User')");
10

11
        // then we expect one result-row with min-degree 0 and max-degree 2
12
        assertTrue(res.hasNext());
13
        Map<String,Object> row = res.next();
14
        assertEquals("User", row.get("label"));
15
        // Dan has no friends
16
        assertEquals(0, row.get("min"));
17
        // Alice knows 2 people
18
        assertEquals(2, row.get("max"));
19
        // We have 4 nodes in our graph
20
        assertEquals(4, row.get("count"));
21
        // only one result record was produced
22
        assertFalse(res.hasNext());
23
    }
24
}




当然,你可以使用存储过程来生成更多的存储过程,比如其他原生支持JVM的语言,比如 JavaScript via Nashorn, Clojure,Groovy, Scala, Frege (Haskell), (J)Ruby or (J/P)ython。

我用JavaScript写了一个生成和运行存储过程的程序。

你还可以用存储过程做很多其他很酷的事情,比如下面列的资源。

如果你有写一些自己的存储过程的想法,请联系我们。

其他资源

Neo4j手册: Calling & Writing Procedures

GitHub Repository for this example

Jacob Hansson's Procedure Template 手动索引更新和查询

Mark Needham写的一篇博客 Graph Algorithm Procedure Blog Post

APOC Utility procedures, JSON, Loading, Collection Handling, Timestamps

Creating JavaScript based Procedures

Graph Refactorings
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

每日签到,有金币领取。


Copyright ©2011-2024 NTpcb.com All Right Reserved.  Powered by Discuz! (NTpcb)

本站信息均由会员发表,不代表NTpcb立场,如侵犯了您的权利请发帖投诉

( 闽ICP备2024076463号-1 ) 论坛技术支持QQ群171867948 ,论坛问题,充值问题请联系QQ1308068381

平平安安
TOP
快速回复 返回顶部 返回列表