NoSQL实践——Neo4j

NOSQL——Neo4j

1,  介绍&配置

近几年互联网大数据的不断发展导致了各种DBMS的发展,除了传统的RDBMS(关系型DBMS),NOSQL发展也较迅速,最著名的是文本型数据库Mongodb,今天介绍的是一种基于图的NOSQL——Neo4j。适合一些图型数据(如下图)的存储,比如社交关系网络等。

 

从官网上可以获得更详细的介绍和下载,下载分三个版本——社区版(Community)、高级版(Advanced)和企业版(Enterprise),一般个人使用Community Edition就可以了,或者可以使用Advanced Edition,不过常用的功能都是一样的。建议选择1.9M02版本以后的,因为对数据查询进行了优化。执行效率更好点。

 

下载后解压缩到某目录下,配置系统的环境变量。类似Java,添加/bin到系统路径中。

 

之后在命令行里安装服务,将Neo4j作为系统的一个服务部署。一般安装的同时也会启动数据库。如下所示:

 

运行成功后即可进行各项操作。如果失败,一般是系统权限问题,可以尝试用管理员权限运行。

 

2,  存储

Neo4j的存储主要分为两种,一种是内嵌在项目中的。还有一种是服务器端配置的。项目内嵌偏重小型个人项目,而服务端的则是可以构建稍大规模的项目甚至生产级的项目。

至于逻辑存储方式,neo4j采用文件存储,整个数据库是由多个文件组成,包括数据、索引等。值得一提的是Neo4j采用lucene作为索引引擎,在索引效率上还算不错。

 不过需要补充的是,不大清楚Neo4j在分布式存储方面的可用性如何,这方面我还没怎么深入,如果可以部署到分布式存储环境的话,那更好了。

3,  Cypher查询

类似于RDBMS的SQL语言,Neo4j也有独立的数据库查询语言——Cypher,其实看过黑客帝国的人应该熟悉,这里各个术语基本都和黑客帝国里的角色相关,或许这也是设计者的初衷。计算机网络其实就是一张巨大的拓扑图结构。

在配置Neo4j服务成功后,可以通过命令行打开Cypher查询界面,命令行中输入命令 Neo4jShell即可,如下所示:


具体到相关的语言特征,和传统的SQL类似,但是增加了不少图的元素。可以输入help查看相关信息,或者访问官方文档,有几个典型的查询:

1),查询。

一般以start命令开始,例如,查看当前Node数:


这里有几个典型的cypher句法,START 关键字用于表征从某个指定点开始,好比在一张网中确定入口点。 node(*) 表示从所有点,如果指定了点的ID的话需要改成node(0)等,事实上,在Neo4j中新建点的时候的都会自动设置一个独特的Id作为其唯一标识符。RETURN 返回结果,COUNT 则是Cypher的内置函数,还有SUM等。这些都可以在官方主页上查到。

返回的结果以列数据的形式展示,第一行是Column的名字,即return 语句后的指定值。接下来是结果,这里是COUNT函数,所以返回的是计数值,如果是点的话,就会返回具体每个点的信息,如下:


在Neo4j中,每个节点或关系的信息以key-value键值对来保存。这算是比较流行的一种方式,在分布式环境或一些NoSql中都会采用这种方式。


2),遍历。

遍历是Neo4j一个重要的功能,也是图数据库所具有的优势之一。传统的RDBMS或者一些文档型NoSql中,遍历往往就是简单的join操作后再加上不断的select等操作

或类似操作,但是在图数据库中遍历操作比较形象,因为可以想象在图,包括有向图和无向图中的遍历,这其实和数据结构中图操作类似,而且Cypher语言中,将

遍历也展示很形象。例如:


这是有向图的遍历,再如:


这又是无向图的遍历。

PS:开始先创建了这个简单的图关系:如下:


可以看出,首先,Cypher语言的易于理解性,包括match,where等关键字的使用。一般都可以看懂遍历的意思,不像其他的SQL遍历语句。

其次,遍历返回的结果展示也是类似图的展示,包括开始节点,中间结点和节点与节点之间的关系。比较形象。

更令人兴奋的是,在Neo4j中可以运用那些经典的图算法,最短路径算法,如Dijkstra算法,Ford算法等。这些都是Neo4j内置的算法。利用这些算法,可以在较大

规模的图中快速高效得到指定点的最短路径,这些在社交网络数据的分析中比较有用。


4,  REST API

之前介绍的主要是针对Neo4j本省的操作,事实上,如果需要在应用中使用Neo4j的话,我们就需要其提供的接口,Neo4j主要提供了两种接口,一种是内嵌式

(Embeded)数据库接口,这个主要用于小型个人的应用,利用Java操作。还有一种是比较共用的,利用REST API接口,作为主要的Web服务接口之一,

REST API的更多介绍可以点击这里

Neo4j采用REST API,其默认端口是7474,我们可以在浏览器里输入 http://localhost:7474,得到界面是Neo4j控制台,当然,这个和下面用到的REST API没太大关系,

就是让Neo4j看起来比较人机交互点。


Neo4j 有很多版本的REST API实现,基本覆盖主流语言,常用的有Java,Python等。具体可以参考这里。

下面就以Java为例,看一下具体的一些使用。

这是连接方法:

        private final static String ROOT_URI="http://localhost:7474/db/data";
	private static WebResource resource;
	private static ClientResponse response;
	
	private static  void Connection(){
		resource=Client.create().resource(ROOT_URI);
		
		response=resource.get(ClientResponse.class);
		System.out.println(response.toString());
		if(response.getStatus()==200){
			System.out.println("Connected Now...");
		}else{
			System.out.println("Not Connected!!");
		}
	}

需要注意的是,先要在项目里导入需要的依赖jar包,即Neo4j本身自带的lib包,还有Java的REST API,就在之前提到的那个网站,

然后是一些应用,例如,获得所有Node数据:

public static boolean IsConnected(){
		resource=Client.create().resource(ROOT_URI);
		response=resource.get(ClientResponse.class);
		
		if(response.getStatus()==200){
			response.close();
			return true;
		}else{
			response.close();
			return false;
		}
	}
	
	public static void GetAllNodes(){
		if(IsConnected()){
			String post_uri=ROOT_URI+"cypher";
			String CypherQuery="START n=node(*) return n";
			String queryJson="{\"query\":\""+CypherQuery+"\","+
									"\"param\":{}}";	//这里比较难看,就是简单的Json拼凑,可以提出到单独的方法中
			
			resource=Client.create().resource(post_uri);
			response=resource.accept(MediaType.APPLICATION_JSON)
									.type(MediaType.APPLICATION_JSON)
									.entity(queryJson)
									.post(ClientResponse.class);
			
			if(response.getStatus()==200){
				System.out.println("Status OK");
				System.out.println(response.getEntity(String.class));
			}else{
				System.out.println("ERROR "+response.getStatus()+"\n"+response.getEntity(String.class));
			}
		}else{
			System.out.println("Connection Refused...");
			System.exit(0);
		}
	}

这里代码就比较多了,大概意思是先连接到服务器(这里就是localhost,实际可以配置为服务器IP地址),然后利用REST API和Cypher查询来获取所有的节点数据。

返回的节点数据是Json格式,具体怎么解析Json想必大家都有办法,这是返回的部分数据,可以看一下:


[ {
    "outgoing_relationships" : "http://localhost:7474/db/data/node/1/relationships/out",
    "data" : {
      "name" : "text"
    },
    "traverse" : "http://localhost:7474/db/data/node/1/traverse/{returnType}",
    "all_typed_relationships" : "http://localhost:7474/db/data/node/1/relationships/all/{-list|&|types}",
    "property" : "http://localhost:7474/db/data/node/1/properties/{key}",
    "self" : "http://localhost:7474/db/data/node/1",
    "properties" : "http://localhost:7474/db/data/node/1/properties",
    "outgoing_typed_relationships" : "http://localhost:7474/db/data/node/1/relationships/out/{-list|&|types}",
    "incoming_relationships" : "http://localhost:7474/db/data/node/1/relationships/in",
    "extensions" : {
    },
    "create_relationship" : "http://localhost:7474/db/data/node/1/relationships",
    "paged_traverse" : "http://localhost:7474/db/data/node/1/paged/traverse/{returnType}{?pageSize,leaseTime}",
    "all_relationships" : "http://localhost:7474/db/data/node/1/relationships/all",
    "incoming_typed_relationships" : "http://localhost:7474/db/data/node/1/relationships/in/{-list|&|types}"
  } ]


可以看出,除了data键对应的是节点本身的数据外,其他的都是REST API格式,这样方便继续调用REST API。

还需要注意的是,这是节点的数据,当然,在图中除了节点还有关系数据,获取方法和节点类似,先确定好REST API,之后就是GET或POST的过程了。
具体可以继续参考REST API文档


5,总结

以上仅仅是Neo4j的一个入门,其实可挖掘的内容还有很多,总的来说,对于图数据库领域,Neo4j做的不错,而且在这个领域还没有太多关注,不过,随着这几年NoSql
越来越火,这些领域逐渐会为人所熟悉。
其实图数据库在一些领域具有相当好的发展空间,比如社交网络的构建与分析,在企业中一些数据节点的分析,甚至在一些分布式环境下对于数据的监控,比如Hadoop中
对NameNode和DataNode的监控。可以运用图数据库的一些特点。

你可能感兴趣的:(NoSql)