第 10 章 扩展 Neo4j 服务器

优质
小牛编辑
129浏览
2023-12-01

目录

10.1. 服务器插件

10.2. 非托管扩展

Neo4j服务器可以通过插件或者非托管扩展来增强。为了获取更多关于服务器的信息,请参考:第 17 章 Neo4j服务器。

10.1. 服务器插件

内容提示

- 服务器的功能可以通过增加插件的方式来增强。

- 插件是用户自己编码完成的,以便增强数据库,节点以及属性的功能。

- Neo4j服务器在与客户端通过HTTP方式进行交互时使用这些自定义插件。

插件提供了一种增加Neo4j Rest API新功能的很好的方式,而不需要去从新发明你自己的API。作为在服务端运行的脚本,插件可以用于接受和维护节点,关系,路径,属性以及指数。

提示

如果你想完全控制你的API,你需要多花心思,并理解这样做的风险,而Neo4j服务端也可以通过JAX-RS提供非托管的扩展。

涉及到的类在jar包org.neo4j:server-api中,看看下载页面的链接地址,介绍了如何引入。对于一个Maven工程,新增 服务端 API依赖到你的工程中,你可以修改 pom.xml像下面这样:

1

2

3

4

5

<dependency>

<groupId>org.neo4j</groupId>

<artifactId>server-api</artifactId>

<version>${neo4j-version}</version>

</dependency>

_ ${neo4j-version} 是一个版本号。_

为了创建插件,你的代码必须继承类: ServerPlugin。你的插件必须做到下面几点:

- 确定插件可以产生一个(一组)节点,关系或者路径,或者任何Java原生类型以及字符串

- 可以指定参数,

- 可以指定一个扩展点

- 包括应用逻辑。

- 确定在 @PluginTarget和 @Source参数中可以发现类型。

下面是一个插件的范例,参数是数据库(也可以是节点或者关系):

获取所有节点和关系的插件.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

@Description( "An extension to the Neo4j Server for getting all nodes or relationships")

publicclassGetAll extendsServerPlugin

{

@Name( "get_all_nodes")

@Description( "Get all nodes from the Neo4j graph database")

@PluginTarget( GraphDatabaseService.class)

publicIterable<Node> getAllNodes( @SourceGraphDatabaseService graphDb )

{

returnGlobalGraphOperations.at( graphDb ).getAllNodes();

}

@Description( "Get all relationships from the Neo4j graph database")

@PluginTarget( GraphDatabaseService.class)

publicIterable<Relationship> getAllRelationships( @SourceGraphDatabaseService graphDb )

{

returnGlobalGraphOperations.at( graphDb ).getAllRelationships();

}

}

完整源代码下载地址: GetAll.java

找到两点之间最短距离的插件.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

publicclassShortestPath extendsServerPlugin

{

@Description( "Find the shortest path between two nodes.")

@PluginTarget( Node.class)

publicIterable<Path> shortestPath(

@SourceNode source,

@Description( "The node to find the shortest path to.")

@Parameter( name = "target") Node target,

@Description( "The relationship types to follow when searching for the shortest path(s). "+

"Order is insignificant, if omitted all types are followed.")

@Parameter( name = "types", optional = true) String[] types,

@Description( "The maximum path length to search for, default value (if omitted) is 4.")

@Parameter( name = "depth", optional = true) Integer depth )

{

Expander expander;

if( types == null)

{

expander = Traversal.expanderForAllTypes();

}

else

{

expander = Traversal.emptyExpander();

for( inti = 0; i < types.length; i++ )

{

expander = expander.add( DynamicRelationshipType.withName( types[i] ) );

}

}

PathFinder<Path> shortestPath = GraphAlgoFactory.shortestPath(

expander, depth == null? 4: depth.intValue() );

returnshortestPath.findAllPaths( source, target );

}

}

完整源代码下载地址: ShortestPath.java

为了部署代码,可以简单的编译成.jar 文件并把他放到服务器的classpath下面(按照惯例,插件目录在Neo4j 服务端的主目录下面)。

提示

确保通过Maven或者 `jar -cvf myext.jar *`编译时,目录列表被保留在jar文件中,确定jar目录代替指定的单个文件。

'.jar' 文件必须包括 'META-INF/services/org.neo4j.server.plugins.ServerPlugin' 。

这是一个范例,有多个入口,每一个都在下面独立的一行:

1

2

3

org.neo4j.examples.server.plugins.GetAll

org.neo4j.examples.server.plugins.DepthTwo

org.neo4j.examples.server.plugins.ShortestPath

上面的代码让一个扩展在接收来自Neo4j 服务端的服务时,总是在数据库中可见(通过 @PluginTarget注解)。简单的改变 @PluginTarget参数成 Node.class或者 Relationship.class,就可以让我们轻松的切换到我们希望的其他数据模型。通过插件提供的功能性扩展会自动生效的。比如,客户端与服务端交互时,可以通过上面的插件提供的扩展,更早的检查他们接收到的反馈。比如在默认数据库URI上发送一个 GET请求:

1

curl -vhttp://localhost:7474/db/data/

对于 GET请求的反馈是默认情况下会是一个JSON数据,里面有一属性”extensions“,列出了所有可以使用的插件。在下面例子中,我们只有 GetAll插件注册到了服务端,所以只有他的扩展功能是可以使用的。扩展名如果没有通过 @Name指定的话会被自动分配,基于方法名。

1

2

3

4

5

6

7

8

9

10

11

12

13

{

"extensions-info": "http://localhost:7474/db/data/ext",

"node": "http://localhost:7474/db/data/node",

"node_index": "http://localhost:7474/db/data/index/node",

"relationship_index": "http://localhost:7474/db/data/index/relationship",

"reference_node": "http://localhost:7474/db/data/node/0",

"extensions_info": "http://localhost:7474/db/data/ext",

"extensions": {

"GetAll": {

"get_all_nodes": "http://localhost:7474/db/data/ext/GetAll/graphdb/get_all_nodes",

"get_all_relationships": "http://localhost:7474/db/data/ext/GetAll/graphdb/getAllRelationships"

}

}

在两个扩展URI上面做 GET请求获取meta信息:

1

curl http://localhost:7474/db/data/ext/GetAll/graphdb/get_all_nodes

1

2

3

4

5

6

{

"extends": "graphdb",

"description": "Get all nodes from the Neo4j graph database",

"name": "get_all_nodes",

"parameters": [ ]

}

为了使用它,需要 POST到这个地址,并带上指定的参数和JSON数据。比如我们调用 shortest path扩展(URI通过发送 GET请求到 http://localhost:7474/db/data/node/123获取 ):

1

2

3

curl -X POST http://localhost:7474/db/data/ext/GetAll/node/123/shortestPath\

-H "Content-Type: application/json"\

-d '{"target":"http://localhost:7474/db/data/node/456&depth=5"}'

如果一切顺利,将返回状态码: 200和一些0或者更多的数据。如果没有任何返回,将返回状态码: 204。如果扩展出现异常,将返回状态码: 500以及异常错误信息。

那些需要进行写操作的扩展必须管理他们自己的事务。事务不能自动被管理的。

通过这个模型,任何插件都会很自然的适应任何Neo4j支持的超媒体 — 这意味着客户端在像节点,关系和路径这些抽象的一个简单的升级路径上占有优势,因为服务端已经被插件增强了(老客户端不会)。

10.2. 非托管扩展

内容提示

- 危险:Men at Work! 非托管扩展是部署随意的JAX-RS代码进Neo4j服务器的一种方式。

- 非托管扩展更准确的说是:非托管。 如果你把没有经过完整单元测试的代码放入了服务器,有很高的几率会降低服务器性能,所以请小心使用。

一些工程希望更加友好的管控他们的服务端代码。为此,我们将介绍一些非托管API。

警告

这是一把双刃剑,它允许用户随意部署 JAX-RS类到服务端,因此你要小心使用。特别是你应该明白,他会轻易的就占用服务端的大量的堆空间,降低你可能不关心的服务端的性能。

当然,如果你了解这些,你可以简单的通过一个 @Context注解加入到你的代码,然后把你的JAX-RS类编译成JAX-RS jar文件,加载进Neo4j服务端。然后增加你的类到运行时路径(classpath)中(只需要把他放到Neo4j服务端的目录中)。你可以使用通过 org.neo4j.server.logging.Logger使用日志功能,获取Neo4j服务端的主机环境信息。

在你的代码中,你可以通过 @Context访问 GraphDatabaseService:

1

2

3

4

publicMyCoolService( @ContextGraphDatabaseService database )

{

// Have fun here, but be safe!

}

记住,非托管API是一种非常高效的工具。他是通过部署代码来影响服务器的最容易的方式,因此我们首先应该想到的是你不能优先使用非托管扩展。然而,大量的上下文参数可以提供给你,像数据库引用。

为了指定你的扩展的挂载点,完整的类应该像这样:

非托管扩展范例.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

@Path( "/helloworld")

publicclassHelloWorldResource

{

privatefinalGraphDatabaseService database;

publicHelloWorldResource( @ContextGraphDatabaseService database )

{

this.database = database;

}

@GET

@Produces( MediaType.TEXT_PLAIN )

@Path( "/{nodeId}")

publicResponse hello( @PathParam( "nodeId") longnodeId )

{

// Do stuff with the database

returnResponse.status( Status.OK ).entity(

( "Hello World, nodeId="+ nodeId ).getBytes() ).build();

}

}

范例源代码下载地址: HelloWorldResource.java

编译这些代码,并把编译的jar文件(包括其他任何依赖包)放到 $NEO4J_SERVER_HOME/plugins目录中,包括在 neo4j-server.properties文件中的类。像下面这样:

提示

确保通过Maven或者 jar -cvf myext.jar *构建的jar文件包括了目录清单,确保用jar目录代替单个文件。

1

2

#包含JAXRS资源的JAXRS包被逗号分隔开,一个包名对应一个挂载点。

org.neo4j.server.thirdparty_jaxrs_classes=org.neo4j.examples.server.unmanaged=/examples/unmanaged

将hello方法绑定到 GET后的地址是: http://{neo4j_server}:{neo4j_port}/examples/unmanaged/helloworld/{nodeId}

1

curl http://localhost:7474/examples/unmanaged/helloworld/123

输出结果:

1

Hello World, nodeId=123

部分 III. 参考

The reference part is the authoritative source for details on Neo4j usage. It covers details on capabilities, transactions, indexing and queries among other topics.

目录

11. 性能

11.1. 数据安全性

11.2. 数据完整性

11.3. 数据集成

11.4. 可用性和可靠性

11.5. 容量

12. 事务管理

12.1. Interaction cycle

12.2. Isolation levels

12.3. Default locking behavior

12.4. Deadlocks

12.5. Delete semantics

12.6. Creating unique nodes

12.7. Transaction events

13. 数据导入

13.1. 批量插入

14. 索引

14.1. Introduction

14.2. Create

14.3. Delete

14.4. Add

14.5. Remove

14.6. Update

14.7. Search

14.8. Relationship indexes

14.9. Scores

14.10. Configuration and fulltext indexes

14.11. Extra features for Lucene indexes

14.12. Automatic Indexing

15. Cypher查询语言

15.1. 操作符

15.2. 表达式

15.3. 参数

15.4. 标识符

15.5. 备注

15.6. 更新图数据库

15.7. 事务

15.8. Patterns

16. 图形算法

16.1. Introduction

17. Neo4j服务器

17.1. 服务器安装

17.2. 服务器配置

17.3. 设置远程调试

17.4. 使用Neo4j服务器(带Web管理控制台)连接一个Neo4j嵌入数据库

17.5. 服务器性能优化

17.6. 在云计算环境中的服务器安装

17.7. Heroku

18. REST API

18.1. Service root

18.2. Streaming

18.3. Cypher queries

18.4. Nodes

18.5. Relationships

18.6. Relationship types

18.7. Node properties

18.8. Relationship properties

18.9. Indexes

18.10. Unique Indexes

18.11. Automatic Indexes

18.12. Configurable Automatic Indexing

18.13. Traversals

18.14. Built-in Graph Algorithms

18.15. Batch operations

18.16. WADL Support

18.17. Cypher插件

18.18. Gremlin Plugin

19. 在Python中使用Neo4j嵌入模式

19.1. 安装

19.2. Core API

19.3. 索引

19.4. Cypher 查询

19.5. 遍历查询