天天看點

圖資料庫-Neo4j-初探

<header class="article-header">
    

<h1 class="article-title" itemprop="name">
  圖資料庫-Neo4j-初探
</h1>


    
    <a href="/2018/08/17/圖資料庫-Neo4j-初探/" class="archive-article-date">
<time datetime="2018-08-17T05:15:46.000Z" itemprop="datePublished"><i class="icon-calendar icon"></i>2018-08-17</time>
           
</header>

<div class="article-entry" itemprop="articleBody">
  
    <p>本次初探主要學習如何安裝<code>Neo4j</code>,以及<code>Cypher</code>的基本文法。</p>
           

1. 安裝Neo4j

  • Desktop

    版本

    neo4j-desktop

  • Server

    版本(

    Community

    版)

    比較建議安裝這個版本,因為

    Desktop

    版本的老是閃退,且要激活之類的。
    • 下載下傳

      Neo4j

      資料庫

      neo4j-server-community

    • 下載下傳常用算法的插件
      • graph-algorithms

        neo4j-graph-algorithms
      • apoc-procedures

        neo4j-apoc-procedures
      将下載下傳下來的算法插件放入到

      $NEO4J_HOME/plugins

      檔案夾下
    • Service

      版修改配置檔案

      $NEO4J_HOME/conf/neo4j.conf

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
            
      # 解決登入的時候報沒有授權的錯誤
      dbms.security.auth_enabled=false
      # 添加下載下傳的算法插件
      dbms.security.procedures.unrestricted=apoc.*,algo.*
      apoc.import.file.enabled=true
      
      #增加頁緩存到至少4G,推薦20G:
      dbms.memory.pagecache.size=4g
      #JVM堆儲存留記憶體從1G起,最大4G:
      dbms.memory.heap.initial_size=1g
      dbms.memory.heap.max_size=4g
            
    • 啟動/停止 (把

      server

      所在的路徑添加到系統的

      PATH

      )
      1
      2
      3
      4
      5
      6
      7
            
      # 建議将neo4j所在的路徑條件到系統$PATH當中,
      # export NEO4J_HOME="path-to-neo4j"
      $NEO4J_HOME/bin/neo4j start
      $NEO4J_HOME/bin/neo4j console
      $NEO4J_HOME/bin/neo4j stop
      $NEO4J_HOME/bin/neo4j start -u neo4j -p neo4j
      $NEO4J_HOME/bin/cypher-shell
            
      1
            
      CALL dbms.procedures() // 檢視neo4j可用的程序,包括剛剛安裝的插件
            

2. Cypher基本文法

  • Nodes基本文法

    在Cypher裡面通過一對小括号代表一個節點

    • () 代表比對任意一個節點
    • (node1) 代表比對任意一個節點,并給它起了一個别名
    • (:Lable) 代表查詢一個類型的資料
    • (person:Lable) 代表查詢一個類型的資料,并給它起了一個别名
    • (person:Lable {name:”小王”}) 查詢某個類型下,節點屬性滿足某個值的資料
    • (person:Lable {name:”小王”,age:23}) 節點的屬性可以同時存在多個,是一個AND的關系
  • Relationship基本文法

    系用一對-組成,關系分有方向的進和出,如果是無方向就是進和出都查詢

    • —> 指向一個節點
    • -[role]-> 給關系加個别名
    • -[:acted_in]-> 通路某一類關系
    • -[role:acted_in]-> 通路某一類關系,并加了别名
    • -[role:acted_in {roles:[“neo”,”Hadoop“]}]->
  • 建立/删除節點
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
          
    // 插入一個Artist類别的節點,而且這個節點有一個屬性為Name,值為Lady Gaga
    CREATE (a:Artist {Name:"Lady Gaga"})
    
    // 建立并傳回
    CREATE (a:Artist {Name:"Lady Gaga", Gemder:"Femal"}) return a
    
    // 一次性建立多個
    CREATE (a:Album { Name: "Killers"}), (b:Album { Name: "Fear of the Dark"}) 
    RETURN a, b
    
    CREATE (a:Album { Name: "Piece of Mind"}) 
    CREATE (b:Album { Name: "Somewhere in Time"}) 
    RETURN a, b
    
    // 删除節點,如果這個節點和其他節點有連接配接的話,不能單單删除這個節點
    MATCH (a:Album {Name: "Killers"}) DELETE a
    
    // 一次性删除多個節點
    MATCH (a:Artist {Name: "Iron Maiden"}), (b:Album {Name: "Powerslave"}) 
    DELETE a, b
               
    // 删除所有節點
    MATCH (n) DELETE n
          
  • 建立/删除關系
    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
          
    // 對Lady Gaga和專輯PieceOfMind之間建立一個released的關系
    MATCH (a:Artist), (b:Album)
    WHERE a.Name = "Lady Gaga" AND b.Name = "Piece of Mind"
    CREATE (a)-[r:RELEASED]->(b)
    RETURN r
    
    MATCH (a:Artist), (b:Album), (p:Person)
    WHERE a.Name = "Strapping Young Lad" AND b.Name = "Heavy as a Really Heavy Thing" AND p.Name = "Devin Townsend" 
    CREATE (p)-[pr:PRODUCED]->(b), (p)-[pf:PERFORMED_ON]->(b), (p)-[pl:PLAYS_IN]->(a)
    RETURN a, b, p
                                                                                   
    // 删除指定的關系
    MATCH (:Artist)-[r:RELEASED]-(:Album) 
    DELETE r       
    
    MATCH (:Artist {Name: "Strapping Young Lad"})-[r:RELEASED]-(:Album {Name: "Heavy as a Really Heavy Thing"}) 
    DELETE r
                                                                       
    // 删除所有的關系
    MATCH ()-[r:RELEASED]-() 
    DELETE r
                                                                         
    // 清除所有節點和關系                                                                    
    MATCH (n)
    OPTIONAL MATCH
    (n)-[r]-()
    DELETE n,r
              
    // 删除整個資料庫
    MATCH (n) DETACH DELETE n
          
  • 建立/删除限制

    SQL

    一樣,

    Neo4j

    資料庫支援對

    Node

    relationship

    的屬性的

    UNIQUE

    限制
    1
    2
    3
          
    CREATE CONSTRAINT ON (a:Artist) ASSERT a.Name IS UNIQUE
    
    DROP CONSTRAINT ON (a:Artist) ASSERT a.Name IS UNIQUE
          
  • 建立/删除索引
    1
    2
    3
    4
    5
    6
          
    CREATE INDEX ON :Album(Name)
                   
    // View the schema
    :schema
    
    DROP INDEX ON :Album(Name)
          
  • 更新一個節點/邊
    1
    2
          
    MATCH (n:Person { name: "Andres" })
    SET n.name = "Taylor";
          
  • 篩選過濾
    1
    2
    3
    4
    5
    6
    7
    8
    9
          
    // WHERE
    MATCH (p1: Person)-[r:friend]->(p2: Person) 
    WHERE p1.name=~"K.+" or p2.age=24 or "neo" in r.rels 
    RETURN p1, r, p2
                                     
    // NOT                                 
    MATCH (p:Person)-[:ACTED_IN]->(m)
    WHERE NOT (p)-[:DIRECTED]->()
    RETURN p, m
          
  • 結果集傳回
    1
    2
    3
    4
    5
          
    MATCH (p:Person)
    RETURN p, p.name AS name, upper(p.name), coalesce(p.nickname,"n/a") AS nickname, { name: p.name,  label:head(labels(p))} AS person
                                                                                                                  
    MATCH (n) 
    RETURN DISTINCT n.name;
          
  • 聚合函數

    Cypher

    支援

    count

    ,

    sum

    avg

    min

    max

    聚合的時候

    null

    會被跳過

    count

    文法 支援

    count( distinct role )

    1
    2
    3
    4
    5
    6
          
    MATCH (actor:Person)-[:ACTED_IN]->(movie:Movie)<-[:DIRECTED]-(director:Person)
    RETURN actor,director,count(*) AS collaborations
    
    //  收集聚合結果
    MATCH (m:Movie)<-[:ACTED_IN]-(a:Person)
    RETURN m.title AS movie, collect(a.name) AS cast, count(*) AS actors
          
  • 排序和分頁
    1
    2
    3
          
    MATCH (a:Person)-[:ACTED_IN]->(m:Movie)
    RETURN a, count(*) AS appearances
    ORDER BY appearances DESC SKIP 3 LIMIT 10;
          
  • Union

    聯合
    1
    2
    3
    4
    5
          
    MATCH (actor:Person)-[r:ACTED_IN]->(movie:Movie)
    RETURN actor.name AS name, type(r) AS acted_in, movie.title AS title
    UNION (ALL)
    MATCH (director:Person)-[r:DIRECTED]->(movie:Movie)
    RETURN director.name AS name, type(r) AS acted_in, movie.title AS title
          
  • With

    語句

    with

    語句給

    Cypher

    提供了強大的

    pipeline

    能力,可以一個或者

    query

    的輸出,或者下一個

    query

    的輸入 和

    return

    語句非常類似,唯一不同的是,

    with

    的每一個結果,必須使用别名辨別。

    使用

    with

    我們可以在查詢結果裡面在繼續嵌套查詢。
    1
    2
    3
    4
          
    MATCH (p:Person)-[:ACTED_IN]->(m:Movie)
    WITH p, count(*) AS appearances, COLLECT(m.Title) AS movies
    WHERE appearances > 1
    RETURN p.name, appearances, movies
          
    有點類似

    SQL

    中的

    having

    ,這裡是

    with

    +

    where

    兩個一起來實作的。
  • 查詢最短路徑
    1
    2
          
    MATCH (ms:Person { name: "Node A" }),(cs:Person { name:"Node B" }), p = shortestPath((ms)-[r:Follow]-(cs)) 
                                                                                         RETURN p;
          
  • 加載資料

    Cypher Neo4j Couldn’t load the external resource

    neo4j初探

    加載存在本地

    server

    上的資料,會在路徑前面自動加個字首

    /path-to-neo4j/neo4j-community-3.4.5/import

    ,即

    Server

    對應所在的路徑下的

    import

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
          
    // 加載address
    LOAD CSV WITH HEADERS FROM "file:///data/addresses.csv" AS csvLine
    CREATE (p:Person {id: toInt(csvLine.id), email: csvLine.address })
    
    
    // 加載email
    LOAD CSV WITH HEADERS FROM "file:///data/emails.csv" AS csvLine
    CREATE (e:Email {id: toInt(csvLine.id), time: csvLine.time, content: csvLine.content })
                          
                          
    // 建立收發關系
    USING PERIODIC COMMIT 500  // 分段加載
    LOAD CSV WITH HEADERS FROM "file:///data/relations.csv" AS csvLine
    MATCH (p1:Person {id: toInt(csvLine.fromId)}),(e:Email { id: toInt(csvLine.emailId)}),(p2:Person{ id: toInt(csvLine.toId)})
    CREATE UNIQUE (p1)-[:FROM]->(e)
    CREATE(e)-[:TO]->(p2)
          
    如果需要導入其他地方的,可以使用
    1
    2
    3
    4
    5
    6
    7
    8
    9
          
    LOAD CSV FROM "https://path-to-csv" AS csvLine
    CREATE (:Genre {GenreId: csvLine[0], Name: csvLine[1]})
    
    // 使用csv中的header                                                   
    LOAD CSV WITH HEADERS FROM "https://path-to-csv" AS csvLine
    CREATE (:Genre {GenreId: csvLine.Id, Name: csvLine.Track, Length: csvLine.Length})  
                     
    // 自定義csv檔案中的分隔符
    LOAD CSV WITH HEADERS FROM "https://path-to-csv" AS csvLine FIELDTERMINATOR ";"
          
  • neo4j-import

    導入資料

    使用neo4j-import導入資料

    • 使用條件
      • 需要先關閉

        neo4j

      • 無法再原有的資料庫添加,隻能重新生成一個資料庫
      • 導入檔案格式為

        csv

    • 參數
      • —into:資料庫名稱
      • —bad-tolerance:能容忍的錯誤資料條數(即超過指定條數程式直接挂掉),預設1000
      • —multiline-fields:是否允許多行插入(即有些換行的資料也可讀取)
      • —nodes:插入節點
      • —relationships:插入關系
      • 更多參數可允許指令

        bin/neo4j-import

    1
          
    bin/neo4j-import --multiline-fields=true --bad-tolerance=1000000 --into graph.db --id-type string --nodes:person node.csv  --relationships:related relation_header.csv,relation.csv
          
    運作完後,将生成的

    graph.db

    放入

    data/databases

    ,覆寫原有資料庫,啟動運作即可

3. References

  • Neo4j的簡單搭建與使用
  • Neo4j Tutorial
  • Neo4j的查詢文法筆記
  • 官方文檔:Comprehensive-Guide-to-Graph-Algorithms-in-Neo4j-ebook
<div class="page-reward">
      <a href="javascript:;" class="page-reward-btn tooltip-top">
        <div class="tooltip tooltip-east">
        <span class="tooltip-item">
          賞
        </span>
        <span class="tooltip-content">
          <span class="tooltip-text">
            <span class="tooltip-inner">
              <p class="reward-p"><i class="icon icon-quo-left"></i>Thanks for your donate.<i class="icon icon-quo-right"></i></p>
              <div class="reward-box">
                
                <div class="reward-box-item">
                  <img class="reward-img" src="/images/alipay.jpeg">
                  <span class="reward-type">支付寶</span>
                </div>
                
                
              </div>
            </span>
          </span>
        </span>
      </div>
      </a>
    </div>
  
</div>
<div class="article-info article-info-index">
  
  
<div class="article-tag tagcloud">
	<i class="icon-price-tags icon"></i>
	<ul class="article-tag-list">
		 
    		<li class="article-tag-list-item">
    			<a href="javascript:void(0)" class="js-tag article-tag-list-link color5">圖資料庫</a>
    		</li>
  		 
    		<li class="article-tag-list-item">
    			<a href="javascript:void(0)" class="js-tag article-tag-list-link color1">Neo4j</a>
    		</li>
  		
	</ul>
</div>
           
<div class="clearfix"></div>
</div>
           

原文位址:https://chenson.cc/2018/08/17/圖資料庫-Neo4j-初探/