neo4j简单学习

背景

最近在一些论坛或者新闻里看到了neo4j,一种擅长处理图形的数据库。 据说非常适合做一些join关系型的查询,所以抽空也看了下相关文档,给自己做个技术储备。

 

过程

深入学习之前,先在网上找了一下别人的一个学习文档总结,踩在别人的肩膀上总是最快,最有效的学习。

 

顺着这些思路,逐步查看一些neo4j的相关wiki文档,摘录了一张图: 

neo4j的基本模型图: 




针对图中的一些基本概念: 
  • node : 节点
  • relationships : 关系,也就是图中的边,注意是有向边
  • properties : 属性,针对node/relationship都可以设置property
  • Traversal :  图遍历工具
  • Indexes :  索引
通过node和relationship就可以组成一个有向图,通过property就可以使其带上对应的数据,成为对应的图像数据库。

node(节点)

  1. 每个节点可以和多个节点之间建立多个关系(relationship)
  2. 单个节点可以设置多个(Key,Value)的properties属性的键值对

relationships(关系)

  1. 每个关系都会包含一个startNode和endNode
  2. 每个关系可以设置多个(Key,Value)的properties属性的键值对
  3. 可以为关系定义对应的关系类型(RelationshipType)
    *  DynamicRelationshipType 动态关系类型
    *  XXXRelationshipType 静态关系类型(实现了RelationshipType接口)

Traversal(遍历)

traverser :  http://wiki.neo4j.org/content/Traversal

一个例子: 

 

Traverser trav = swedenNode.traverse(Order.DEPTH_FIRST, StopEvaluator.END_OF_GRAPH,
    new ReturnableEvaluator()
    {
        public boolean isReturnableNode( TraversalPosition pos )
        {
            return !pos.isStartNode() && pos.lastRelationshipTraversed().isType( CUSTOMER_TO_ORDER );
        }
    },
    LIVES_IN, Direction.INCOMING,
    CUSTOMER_TO_ORDER, Direction.OUTGOING );
// iterate over traverser...

 

Order : 对应的图的遍历算法

 

  • DEPTH_FIRST :  深度优先搜索,就是找到第一个节点,递归的一直往下找,直到找不到合适的节点后,才进行回溯
  • BREADTH_FIRST :  广度优先搜索
Direction :对应图中edge的方向
  • OUTGOING : 出边
  • INCOMING : 入边
  • BOTH : 顾明思议
StopEvaluator : 定义图搜索的停止条件,默认有两个
  • DEPTH_ONE :  深度超过1后停止
  • END_OF_GRAPH :  无合适结果和停止
ReturnableEvaluator : 结果处理器,可以设置对应的返回结果,默认有:
  • ALL_BUT_START_NODE :  排除初始节点
  • ALL : 返回所有节点
TraversalPosition : 对应搜索过程中的node节点信息,包括:
  • 上一个节点信息
  • 上一个进入的Relationship信息
  • 搜索深度
  • 目前为止满足条件的节点数

Indexs(索引)

neo4j中针对每个node/relationship/property都是进行独立存储,都是按照自然的顺序。为了支持一些场景,比如针对关系型数据库的根据主键name查询对应的person node,普通的Traversal很难满足这样的需求,而且人家也不是用来解决这个事的。所以neo4j就引出了一个index的概念。 

 

早期的版本的index是采用了IndexService(http://wiki.neo4j.org/content/Indexing_with_IndexService)

一个例子:

 

GraphDatabaseService graphDb = new EmbeddedGraphDatabase( "path/to/neo4j-db" );
IndexService index = new LuceneIndexService( graphDb );

Node andy = graphDb.createNode();
Node larry = graphDb.createNode();

andy.setProperty( "name", "Andy Wachowski" );
andy.setProperty( "title", "Director" );
larry.setProperty( "name", "Larry Wachowski" );
larry.setProperty( "title", "Director" );
index.index( andy, "name", andy.getProperty( "name" ) );
index.index( andy, "title", andy.getProperty( "title" ) );
index.index( larry, "name", larry.getProperty( "name" ) );
index.index( larry, "title", larry.getProperty( "title" ) );

 

IndexService是做为外部的component进行扩展定义。 

 

现在官方文档中是建议使用Integrated Index Framework

 

  1. 官方文档: http://docs.neo4j.org/chunked/stable/indexing.html
  2. 迁移方案: http://wiki.neo4j.org/content/Transitioning_To_Index_Framework
新版本例子: 
IndexManager index = graphDb.index();
Index<Node> actors = index.forNodes( "actors" );
Index<Node> movies = index.forNodes( "movies" );
RelationshipIndex roles = index.forRelationships( "roles" );
从新版本中,已经将index做为其内核的实现,并不是外部扩展包的机制,从而可见其重要性阿,想了解具体的内容可以详细看下对应的官方文档。

查询语法(Cyphe Query Language)

neo4j自己基于图论的搜索算法,实现了一套查询语言解析,提供了一些常见的聚合函数(max,sum,min,count等)。

 

语法例子:

 

Join查询:
start n=(1) match (n)-[:BLOCKS]->(x) return x

Where条件:
start n=(2, 1) where (n.age < 30 and n.name = "Tobias") or not(n.name = "Tobias") return n

聚合函数:
start n=(2,3,4) return avg(n.property)

Order:
start n=(1,2,3) return n order by n.name DESC

分页:
start n=(1,2,3,4,5) return n order by n.name skip 1 limit 2

 

 

调用例子:

 

db = new ImpermanentGraphDatabase();
engine = new ExecutionEngine( db );
CypherParser parser = new CypherParser();
ExecutionEngine engine = new ExecutionEngine(db);
Query query = parser.parse( "start n=(0) where 1=1 return n" );
ExecutionResult result = engine.execute( query );
assertThat( result.columns(), hasItem( "n" ) );
Iterator<Node> n_column = result.columnAs( "n" );
assertThat( asIterable( n_column ), hasItem(db.getNodeById(0)) );
assertThat( result.toString(), containsString("Node[0]") );

 

其他

现在用nosql,除了一些功能feature问题,很重要的会是关注其他的两点扩展性&可用性

扩展性

暂时未看到有相应的扩展性方案

可用性(HA机制)

目前neo4j支持简单的ha机制,是通过zookeeper进行管理。


 

它的工作机制还是挺简单的,就是由zookeeper负责neo4j server的心跳检测。

1. 发现master挂了后,会发起一个选举(没看过源码,估摸着选举的实现也会很简单,根据对应的serverid,取最小的id做为新的master)。

2. 将新的master广播给所有的slave,此时在选举过程中,不接受对应的write请求(全都是返回异常)
3. 新机器加入集群后,会做为slave于master进行通讯,同步两者的数据内容(如果当前slave的tid比master新,会产生一个数据冲突此时需要进行手工干预)

 

存在的问题:

1. zookeeper心跳检测的及时性,默认为3分钟延迟(因为会有包重试)

2. master选举期间,write请求不可处理,直接返回异常(虽然master的选举时间会相对比较端,但对客户端不够友好)

 

可以改进的点:

1. 提供客户端的api,提供一种failover重试的机制控制。

Console页面

neo4j支持嵌入式和独立部署的两种模式,部署了一下neo4j独立部署server,效果图如下:

 

图形管理后台,可以方面查看节点之间的relationships

 

 

rest接口的api,提供了图形和纯数据的几种方式:

其他文档

 

### 关于 Neo4j学习资料、教程、示例和报告 #### 一、Spring Data Neo4j 集成开发 Spring Data Neo4j 是一个强大的工具,用于简化在 Spring 应用程序中对 Neo4j数据库的数据访问操作。通过该框架,开发者能够以 JPA 风格的方式定义实体类及其关系,并将其映射到 Neo4j 中的节点和边[^1]。这种集成方式使得开发者无需手动编写复杂的 Cypher 查询语句即可完成大部分 CRUD 操作。 对于初学者而言,在构建项目时建议选择较低版本的 Spring Boot(如 2.3.5),以便现有文档保持一致[^2]。随着技术的发展,未来可能需要适应更高版本中的变化。 #### 二、Neo4j 安装配置指南 为了顺利开展实践练习,首先需正确安装并运行本地实例。以下是具体步骤概述: 1. **下载软件包** 访问官方站点获取对应平台的支持文件;注意 JDK 版本兼容性问题——当选用 v4.x 及以上系列时至少要求 Java SE Development Kit 11 或更高级别[^3]。 2. **初始化环境** 解压缩后进入 `bin` 文件夹路径下执行命令行脚本来部署后台进程以及激活前端界面入口点 (`http://localhost:7474`) 登录验证默认凭证组合为用户名:"neo4j", 初始密码同样设置成了 "neo4j". 不过首次连接成功以后强制更改初始口令安全策略生效. #### 三、Cypher 基础教学概览 作为专用领域特定语言(DSL),Cypher 提供了一种简洁优雅的方式来表达复杂模式匹配需求。下面给出几个基础例子帮助理解其工作原理: - 创建两个简单的人员对象并通过指定属性建立关联关系: ```cypher CREATE (alice:Person { name:'Alice', age:30 }) CREATE (bob:Person { name:'Bob', age:28 }) MATCH (a:Person),(b:Person) WHERE a.name='Alice' AND b.name='Bob' CREATE (a)-[r:FRIEND_OF]->(b); RETURN type(r), r; ``` 此片段展示了如何利用 MATCH 子句定位目标记录集,接着运用 CREATE 动作新增一条指向型态的关系链路[FRIEND_OF]. 另外还有更多进阶功能等待探索比如聚合函数计算统计指标或者全文检索支持等等[^4]. --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值