• 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

    一个例子: 

    Java代码  收藏代码
    1. Traverser trav = swedenNode.traverse(Order.DEPTH_FIRST, StopEvaluator.END_OF_GRAPH,  
    2.     new ReturnableEvaluator()  
    3.     {  
    4.         public boolean isReturnableNode( TraversalPosition pos )  
    5.         {  
    6.             return !pos.isStartNode() && pos.lastRelationshipTraversed().isType( CUSTOMER_TO_ORDER );  
    7.         }  
    8.     },  
    9.     LIVES_IN, Direction.INCOMING,  
    10.     CUSTOMER_TO_ORDER, Direction.OUTGOING );  
    11. // iterate over traverser...<span style="white-space: normal;">  
    12. </span>  

    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)

    一个例子:

    Java代码  收藏代码
    1. GraphDatabaseService graphDb = new EmbeddedGraphDatabase( "path/to/neo4j-db" );  
    2. IndexService index = new LuceneIndexService( graphDb );  
    3.   
    4. Node andy = graphDb.createNode();  
    5. Node larry = graphDb.createNode();  
    6.   
    7. andy.setProperty( "name""Andy Wachowski" );  
    8. andy.setProperty( "title""Director" );  
    9. larry.setProperty( "name""Larry Wachowski" );  
    10. larry.setProperty( "title""Director" );  
    11. index.index( andy, "name", andy.getProperty( "name" ) );  
    12. index.index( andy, "title", andy.getProperty( "title" ) );  
    13. index.index( larry, "name", larry.getProperty( "name" ) );  
    14. 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
    新版本例子: 
    Java代码  收藏代码
    1. IndexManager index = graphDb.index();  
    2. Index<Node> actors = index.forNodes( "actors" );  
    3. Index<Node> movies = index.forNodes( "movies" );  
    4. RelationshipIndex roles = index.forRelationships( "roles" );  
    从新版本中,已经将index做为其内核的实现,并不是外部扩展包的机制,从而可见其重要性阿,想了解具体的内容可以详细看下对应的官方文档。

    查询语法(Cyphe Query Language)

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

    语法例子:

    Java代码  收藏代码
    1. Join查询:  
    2. start n=(1) match (n)-[:BLOCKS]->(x) return x  
    3.   
    4. Where条件:  
    5. start n=(21) where (n.age < 30 and n.name = "Tobias") or not(n.name = "Tobias"return n  
    6.   
    7. 聚合函数:  
    8. start n=(2,3,4return avg(n.property)  
    9.   
    10. Order:  
    11. start n=(1,2,3return n order by n.name DESC  
    12.   
    13. 分页:  
    14. start n=(1,2,3,4,5return n order by n.name skip 1 limit 2  

    调用例子:

    Java代码  收藏代码
    1. db = new ImpermanentGraphDatabase();  
    2. engine = new ExecutionEngine( db );  
    3. CypherParser parser = new CypherParser();  
    4. ExecutionEngine engine = new ExecutionEngine(db);  
    5. Query query = parser.parse( "start n=(0) where 1=1 return n" );  
    6. ExecutionResult result = engine.execute( query );  
    7. assertThat( result.columns(), hasItem( "n" ) );  
    8. Iterator<Node> n_column = result.columnAs( "n" );  
    9. assertThat( asIterable( n_column ), hasItem(db.getNodeById(0)) );  
    10. 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,提供了图形和纯数据的几种方式:

    其他文档

        <ul style="display:none;">
          <li><a href="http://dl2.iteye.com/upload/attachment/0052/0645/f2f27cba-8bad-32a5-9c9e-81902070b56f.png" target="_blank"><img src="https://img2018.cnblogs.com/blog/1112483/201909/1112483-20190909111247366-1684275372.png" class="magplus" title="点击查看原始大小图片"></a></li>
          
          <li>大小: 42.7 KB</li>
        </ul>
      
    
      
        <ul style="display:none;">
          <li><a href="http://dl2.iteye.com/upload/attachment/0052/1077/f72f857c-5214-3cd7-a5e7-3815a549727e.png" target="_blank"><img src="https://img2018.cnblogs.com/blog/1112483/201909/1112483-20190909111303154-1917188065.png" class="magplus" title="点击查看原始大小图片"></a></li>
          
          <li>大小: 138.5 KB</li>
        </ul>
      
    
      
        <ul style="display:none;">
          <li><a href="http://dl2.iteye.com/upload/attachment/0052/2869/9b18232b-acbb-353e-9b35-d58ce28e4ceb.png" target="_blank"><img src="http://dl2.iteye.com/upload/attachment/0052/2869/9b18232b-acbb-353e-9b35-d58ce28e4ceb-thumb.png" class="magplus" title="点击查看原始大小图片"></a></li>
          
          <li>大小: 43.8 KB</li>
        </ul>
      
    
      
        <ul style="display:none;">
          <li><a href="http://dl2.iteye.com/upload/attachment/0052/2871/6d548edd-7471-34f3-95ea-ffb0fed32591.png" target="_blank"><img src="http://dl2.iteye.com/upload/attachment/0052/2871/6d548edd-7471-34f3-95ea-ffb0fed32591-thumb.png" class="magplus" title="点击查看原始大小图片"></a></li>
          
          <li>大小: 35.9 KB</li>
        </ul>
      
    
    
      <ul>
        <li><a href="#" onclick="$$('div.attachments ul').invoke('show');$(this).up(1).hide();return false;">查看图片附件</a></li>
      </ul>
    

    原文地址:https://www.iteye.com/blog/agapple-1128400

  • 相关阅读:
    final/override控制
    高效遍历图像
    快速初始化成员变量
    C++ boost.python折腾笔记
    百亿数据毫秒响应级交易系统读写分离存储数据设计
    解决VS2010子目录中的.cpp文件引用上一级目录的stdafx.h找不到定义的问题
    生产应用常见坑
    spring AOP应用
    springmvc No mapping found for HTTP request with URI in Dispatc
    myeclipse使用maven插件进行maven install时报错check $m2_home environment variable and mvn script match
  • 原文地址:https://www.cnblogs.com/jpfss/p/11490535.html
Copyright © 2020-2023  润新知