Skip to content
changwu edited this page Mar 18, 2016 · 39 revisions

Graph Database

其他資源

影片

安裝

$ brew install neo4j

設定檔路徑

/usr/local/Cellar/neo4j/2.3.2/libexec/conf

例如要能遠端連進 neo4j, 可以修改 neo4j-server.properties

啟動 Neo4j

$ neo4j start

預設會運行在 port 7474, 第一次安裝會要求設定密碼, 使用者名稱: neo4j

org.neo4j.server.webserver.address=0.0.0.0

Cypher Query Language

在 Neo4j, query 的語法叫做 Cypher

  • MATCH: 像 SELECT
  • CREATE: 新增 DB, 或新增 relationship
  • WHERE: 條件
  • RETURN: 回傳對象

MATCH

語法起源來自 Ascii art

$ MATCH (user)-[:BIRTH_PLACE]->(country) RETURN user, country;

birth

CREATE

產生 Employee 的節點

  • n: variable
  • Employee: label
  • {}: properties
$ CREATE (n:Employee {Name:"Chang-Wu", Surname: "Chen", Gender: "M"});

RETURN

$ MATCH (n:Employee) RETURN n;
$ MATCH (n:Employee) RETURN n LIMIT 100;
$ MATCH (n:Employee) RETURN n.Gender;

注意 Neo4j 在回傳超過 1000 筆資料時, 會有錯誤, 所以最好的方式是在查詢資料返回時, 加上筆數限制

$ MATCH (n:Employee) RETURN n.Name AS Name, n.Gender AS Gender;

取回資料可用 AS 來重新命名欄位名稱

Neo4j web console 可用來查看 query, 或下指令, 亦可匯出 .json 或 .csv 檔案, 但是無法用來匯入資料, 操作資料透過 command line , 或是利用其他語言 api 來操作 Neo4j 比較好, 另外要繪製圖形需要自己處理, 可以使用其他套件, 例如 d3.js

修改資料可用 SET

$ MATCH (n:Employee {Name:"Chang-Wu"}) SET n.Gender=NULL;

刪除 Name 與 Gender

$ MATCH (n:Employee {Surname:"Chen"}) SET n.Name=NULL RETURN n;

刪除節點

$ MATCH (n:Employee {Surname:"Chen"}) DELETE n;

查看資料庫中所有資料

$ MATCH n RETURN n;

如果要刪除的點, 與其他點之間有關係的話, 必須先移除關係, 才能移除節點.

WHERE

$ MATCH (n:Employee) WHERE n.Name="Chang-Wu" RETURN n;
$ MATCH (n:Employee) WHERE n.Name=~"Cha.*" RETURN n;
$ MATCH (n:Employee) WHERE n.Name STARTS WITH "Ch" RETURN n;

沒有主鍵

在 Neo4j 沒有所謂的 primary key, 換言之, 資料回重複出現兩次

$ CREATE (n:Employee {Name:"Chang-Wu", Surname: "Chen", Gender: "M"});
$ CREATE (n:Employee {Name:"Chang-Wu", Surname: "Chen", Gender: "M"});

Data

$ MATCH n RETURN n;
{
  "results": [
    {
      "columns": [
        "n"
      ],
      "data": [
        {
          "row": [
            {
              "Gender": "M",
              "Surname": "Chen",
              "Name": "Chang-Wu"
            }
          ],
          "graph": {
            "nodes": [
              {
                "id": "2",
                "labels": [
                  "Employee"
                ],
                "properties": {
                  "Gender": "M",
                  "Surname": "Chen",
                  "Name": "Chang-Wu"
                }
              }
            ],
            "relationships": []
          }
        },
        {
          "row": [
            {
              "Gender": "M",
              "Surname": "Chen",
              "Name": "Chang-Wu"
            }
          ],
          "graph": {
            "nodes": [
              {
                "id": "3",
                "labels": [
                  "Employee"
                ],
                "properties": {
                  "Gender": "M",
                  "Surname": "Chen",
                  "Name": "Chang-Wu"
                }
              }
            ],
            "relationships": []
          }
        }
      ],
      "stats": {
        "contains_updates": false,
        "nodes_created": 0,
        "nodes_deleted": 0,
        "properties_set": 0,
        "relationships_created": 0,
        "relationship_deleted": 0,
        "labels_added": 0,
        "labels_removed": 0,
        "indexes_added": 0,
        "indexes_removed": 0,
        "constraints_added": 0,
        "constraints_removed": 0
      }
    }
  ],
  "errors": []
}

但 Neo4j 中, 在生成 node 時, 會有不同的 node id 區別同樣的 data

建立關係

$ CREATE (e:Employee {Name: "Chang-Wu"})-[:WORK_IN]->(c:Company {Name: "Yahoo!"});
$ CREATE (s:Skill {Name: "Neo4j"})<-[:KNOWNS]-(e:Employee {Name: "Chang-Wu"})-[:WORK_IN]->(c:Company {Name:"Yahoo!"});
$ MATCH (e:Employee {Name: "Chang-Wu"}), (s:Skill) WHERE s.Name="Neo4j" CREATE UNIQUE (e)-[:KNOWS]->(s);

CREATE UNIQUE 用來避免資料庫重複新增同樣 data, 前面提過, Neo4j 沒有主鍵, 資料可被重複新增

relationship

找出關係

$ MATCH (e:Employee {Name: "Chang-Wu"})-[r]-(c:Company {Name: "Yahoo!"}) RETURN r;
$ MATCH (e:Employee)-[:KNOWS]->(s:Skill) RETURN e.Name, s.Name;
$ MATCH (e:Employee)-[:KNOWS]->(s:Skill) WHERE s.Name="Neo4j" RETURN e.Name;
$ MATCH (e:Employee)-[r]->(s:Skill) RETURN r;

刪除所有關係

$ start r=relationship(*) delete r;

Python for Neo4j

py2neo

from py2neo import Graph, Node, Relationship

graph = Graph()

a = Node("Person", name="Alice")
b = Node("Person", name="Bob")
ab = Relationship(a, "KNOWS", b, Since=2015)
graph.create(ab)

ab

搜尋

a = graph.find_one("Person", "name", "Alice")
print a

nodes = graph.find("Person")
for node in nodes:
    print node

修改

a = graph.find_one("Person", "name", "Alice")
a.properties["name"] = "Anna"
a.push

刪除

a = graph.find_one("Person", "name", "Alice")
a.delete()

graph.delete_all()  # MATCH (n)-[r]-(q) DELETE n, r, q;

執行 Cypher Query

print graph.cypher.execute("MATCH n RETURN n;")

UNIQUE 另外也很重要, 當不想要重複新增資料

Clone this wiki locally