neo4j REST API

2017-12-30 12:13:59来源:oschina作者:xiaomin0322人点击

分享
neo4j REST API 博客分类: neo4j


2.3.1.1. 从Java中使用REST API创建一张图

REST API使用 HTTP协议传输,数据采用JSON格式,以至于他能被需要计算机语言和平台使用。尽管如此,准备开始使用之前,看一些可以重用的模式是非常有用的。在这 个简短的概述中,我们将为你展示如何通过REST API创建一个或者多个简单图并且查询他里面存在的数据。


为了得到这些范例,我们选择了Jersey客户端组件,他可以通过Maven轻松下载。



2.3.1.2. 启动 Neo4j 服务端

在我们准备在Neo4j服务端做任何操作之前,我们需要先启动他,可以参考:3.7.1. 数据库服务端安装


WebResource resource = Client.create()

.resource( SERVER_ROOT_URI );


ClientResponse response = resource.get( ClientResponse.
class
);


System.out.println( String.format(
"GET on [%s], status code [%d]"
,

SERVER_ROOT_URI, response.getStatus() ) );


response.close();


如果返回的状态码是200 OK, 那我们就确定 Neo4j 服务端已经成功运行,我们可以继续使用了。如果连接到服务端失败,请参考:3.7. Neo4j数据库服务端


注意 如果你获得的返回码大于200 OK(特别是4xx或者5xx ),那请您检查你的配置并查看在目录data/log中的日志。

2.3.1.3. 创建一个节点

REST API 使用POST来创建节点. 在Java中封装的接口使用Jersey客户端便可以非常容易使用:


final
String nodeEntryPointUri = SERVER_ROOT_URI +
"node"
;


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


WebResource resource = Client.create()

.resource( nodeEntryPointUri );


// POST {} to the node entry point URI


ClientResponse response = resource.accept( MediaType.APPLICATION_JSON )

.type( MediaType.APPLICATION_JSON )

.entity(
"{}"
)

.post( ClientResponse.
class
);


final
URI location = response.getLocation();


System.out.println( String.format(

"POST to [%s], status code [%d], location header [%s]"
,

nodeEntryPointUri, response.getStatus(), location.toString() ) );


response.close();


return
location;


如果调用成功完成,他会在后台发送一个包含JSON数据的HTTP请求给服务端。服务端会在数据库中创建一个新的节点并且返回状态码 201 Created 和访问这个新节点的地址。


在我们的范例中,我们将调用这个功能两次以便在数据库中创建两个节点。



2.3.1.4.为节点增加属性

一旦我们在数据库中有了节点,我们可以使用他们来保存有用的数据。在这个范例中,我们将在我们的数据库中保存音乐信息。下面让我们浏览下面的代码, 代码中,我们创建了节点并且给节点增加属性。这里,我们新增一个节点“Joe Strummer”,并且增加了一个属性 “brand”,属性值是: “The Clash”。


URI firstNode = createNode();


addProperty( firstNode,
"name"
,
"Joe Strummer"
);


URI secondNode = createNode();


addProperty( secondNode,
"band"
,
"The Clash"
);


在方法addProperty内部,我们确定了代表节点属性的名称,以及该属性的值。然后我们使用PUT将该属性发送到服务端。


String propertyUri = nodeUri.toString() +
"/properties/"
+ propertyName;


// http://localhost:7474/db/data/node/{node_id}/properties/{property_name}


WebResource resource = Client.create()

.resource( propertyUri );


ClientResponse response = resource.accept( MediaType.APPLICATION_JSON )

.type( MediaType.APPLICATION_JSON )

.entity(
"/""
+ propertyValue +
"/""
)

.put( ClientResponse.
class
);


System.out.println( String.format(
"PUT to [%s], status code [%d]"
,

propertyUri, response.getStatus() ) );


response.close();


如果一切顺利,我们将会得到返回码:204 No Content,表示服务端已经受理这个请求,整个请求不会回显属性的值。



2.3.1.5. 为节点增加关系

现在我们有了表示Joe Strummer 和 The Clash的节点,我们可以关联他们。REST API通过一个POST方式支持对节点建立关系。在Java中相应地,我们POST>一些JSON到节点Joe Strummer的节点地址,确定了该节点和The Clash节点之间的关系。


URI relationshipUri = addRelationship( firstNode, secondNode,
"singer"
,

"{ /"from/" : /"1976/", /"until/" : /"1986/" }"
);


在addRelationship方法中,我们确定了Joe Strummer节点的地址,然后POST一些JSON数据从而建立关系。这些JSON数据包括目标节点,关系的类型以及一些关系的属性等。


private
static
URI addRelationship( URI startNode, URI endNode,

String relationshipType, String jsonAttributes )

throws
URISyntaxException


{

URI fromUri =
new
URI( startNode.toString() +
"/relationships"
);

String relationshipJson = generateJsonRelationship( endNode,

relationshipType, jsonAttributes );

WebResource resource = Client.create()

.resource( fromUri );

// POST JSON to the relationships URI

ClientResponse response = resource.accept( MediaType.APPLICATION_JSON )

.type( MediaType.APPLICATION_JSON )

.entity( relationshipJson )

.post( ClientResponse.
class
);

final
URI location = response.getLocation();

System.out.println( String.format(

"POST to [%s], status code [%d], location header [%s]"
,

fromUri, response.getStatus(), location.toString() ) );

response.close();

return
location;


}


如果一切正常,我们将得到返回码:201 Created和一个地址Location,这个地址是我们刚建立的关系的地址。



2.3.1.6. 为关系增加一个属性

像节点一样,管东西一样拥有属性。自从我们大量关注Joe Strummer和 The Clash以来,我们增加了他们的关系的属性:等级,以至于我们可以看到一个五星级的品牌属性。


addMetadataToProperty( relationshipUri,
"stars"
,
"5"
);


在addMetadataToProperty方法中,我们确定了关系的地址,然后PUT我们新的值到服务端,这些新的值会覆盖过去已经存在的,所以请在操作之前务必谨慎。


private
static
void
addMetadataToProperty( URI relationshipUri,

String name, String value )
throws
URISyntaxException


{

URI propertyUri =
new
URI( relationshipUri.toString() +
"/properties"
);

String entity = toJsonNameValuePairCollection( name, value );

WebResource resource = Client.create()

.resource( propertyUri );

ClientResponse response = resource.accept( MediaType.APPLICATION_JSON )

.type( MediaType.APPLICATION_JSON )

.entity( entity )

.put( ClientResponse.
class
);

System.out.println( String.format(

"PUT [%s] to [%s], status code [%d]"
, entity, propertyUri,

response.getStatus() ) );

response.close();


}


假设一切正常,我们将得到返回码:200 OK(我们也可以通过调用ClientResponse.getStatus()来检查),到此,我们已经建立起了一个小型的图数据库网络,我们已经可以从中查询一些有价值的数据了。



2.3.1.7. 查询

跟图数据嵌入模式一样,Neo4j服务端模式也使用图遍历来查询数据。当前,Neo4j服务端希望得到一个JSON格式的查询请求通过POST发送给他以便遍历数据库。(虽然这在以GET方式传送的适合随时都会发生变化)。


为了启动这个查询,我们使用了一个能做JSON转换的类,准备POST数据到服务端。在这种情况下,我们硬编码到遍历查询条件中,查找所有有类型是"singer"的输出关系的节点。


// TraversalDescription turns into JSON to send to the Server


TraversalDescription t =
new
TraversalDescription();


t.setOrder( TraversalDescription.DEPTH_FIRST );


t.setUniqueness( TraversalDescription.NODE );


t.setMaxDepth(
10
);


t.setReturnFilter( TraversalDescription.ALL );


t.setRelationships(
new
Relationship(
"singer"
, Relationship.OUT ) );


一旦我们确定了遍历的参数,我们只需要转换它。我们确定了遍历的开始节点,然后POST JSON数据到服务端开始查询。


URI traverserUri =
new
URI( startNode.toString() +
"/traverse/node"
);


WebResource resource = Client.create()

.resource( traverserUri );


String jsonTraverserPayload = t.toJson();


ClientResponse response = resource.accept( MediaType.APPLICATION_JSON )

.type( MediaType.APPLICATION_JSON )

.entity( jsonTraverserPayload )

.post( ClientResponse.
class
);


System.out.println( String.format(

"POST [%s] to [%s], status code [%d], returned data: "

+ System.getProperty(
"line.separator"
) +
"%s"
,

jsonTraverserPayload, traverserUri, response.getStatus(),

response.getEntity( String.
class
) ) );


response.close();


一旦这个请求完成,我们将得到我们的歌手的数据集以及他们属于的品牌:


[ {

"outgoing_relationships"
:
"http://localhost:7474/db/data/node/82/relationships/out"
,

"data"
: {

"band"
:
"The Clash"
,

"name"
:
"Joe Strummer"

},

"traverse"
:
"http://localhost:7474/db/data/node/82/traverse/{returnType}"
,

"all_typed_relationships"
:
"http://localhost:7474/db/data/node/82/relationships/all/{-list|&|types}"
,

"property"
:
"http://localhost:7474/db/data/node/82/properties/{key}"
,

"all_relationships"
:
"http://localhost:7474/db/data/node/82/relationships/all"
,

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

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

"outgoing_typed_relationships"
:
"http://localhost:7474/db/data/node/82/relationships/out/{-list|&|types}"
,

"incoming_relationships"
:
"http://localhost:7474/db/data/node/82/relationships/in"
,

"incoming_typed_relationships"
:
"http://localhost:7474/db/data/node/82/relationships/in/{-list|&|types}"
,

"create_relationship"
:
"http://localhost:7474/db/data/node/82/relationships"


}, {

"outgoing_relationships"
:
"http://localhost:7474/db/data/node/83/relationships/out"
,

"data"
: {

},

"traverse"
:
"http://localhost:7474/db/data/node/83/traverse/{returnType}"
,

"all_typed_relationships"
:
"http://localhost:7474/db/data/node/83/relationships/all/{-list|&|types}"
,

"property"
:
"http://localhost:7474/db/data/node/83/properties/{key}"
,

"all_relationships"
:
"http://localhost:7474/db/data/node/83/relationships/all"
,

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

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

"outgoing_typed_relationships"
:
"http://localhost:7474/db/data/node/83/relationships/out/{-list|&|types}"
,

"incoming_relationships"
:
"http://localhost:7474/db/data/node/83/relationships/in"
,

"incoming_typed_relationships"
:
"http://localhost:7474/db/data/node/83/relationships/in/{-list|&|types}"
,

"create_relationship"
:
"http://localhost:7474/db/data/node/83/relationships"


} ]


2.3.1.8.呼,是它吗?

这就是我们使用REST API的方式。自然对于对HTTP协议不了解的,我们提供了对HTTP操作的封装,包括通过DELETE移除节点和关系。当然,如果你想了解更多,你可以尝试在Jersey客户端代码中采用.post()来代替.delete()。



2.3.1.9. 下一步做什么呢?

HTTP API 提供了大量客户端基本操作的实现,也包括HTTP和REST。在将来,虽然 REST API的方式占有一定的优势,但是我们还是期望出现语言级的方式来做客户端,能更轻松的绑定到Neo4j的嵌入模式(比如python)。关于当前 Neo4j REST客户端以及嵌入封装,请查看:http://www.delicious.com/neo4j/drivers。



http://www.neo4j.org.cn/2012/07/30/server-java-rest-client-example/#maodian001




http://docs.neo4j.org.cn/

微信扫一扫

第七城市微信公众平台