Neo4j是一个高性能的, NOSQL图形数据库,它将结构化数据存储在网络上而不是表中。它是一个嵌入式的、基于磁盘的、具备完全的事务特性的Java持久化引擎。Neo4j也可以被看作是一个高性能的图引擎,该引擎具有成熟数据库的所有特性。程序员工作在一个面向对象的、灵活的网络结构下而不是严格、静态的表中——但是他们可以享受到具备完全的事务特性、企业级的数据库的所有好处。
下载Neo4j Community Edition,下载地址:http://neo4j.org/download。
由于是mac下载,直接下载dmg文件。
安装Neo4j Community Edition并打开,配置运行数据存储路径,配置完毕后点击start启动。
3. Neo4j的远程可视化操作
打开 options ,找到 .neo4j.conf,取消以下代码的注释
dbms.connectors.default_listen_address=0.0.0.0
插入一个Person类别的节点,且这个节点有一个属性name,属性值为Andres。
CREATE (n:Person {name : 'Andres'});
MATCH (a:Person),(b:Person)
WHERE a.name = 'Node A' AND b.name = 'Node B'
CREATE (a)-[r:Follow]->(b);
MATCH (n:Person { name: 'Andres' })
SET n.name = 'Taylor';
MATCH (n:Person { name:'Taylor' })
DETACH DELETE n;
MATCH (a:Person)-[r:Follow]->(b:Person)
WHERE a.name = 'Node A' AND b.name = 'Node B'
DELETE r;
MATCH (ms:Person { name:'Node A' }),(cs:Person { name:'Node B' }), p = shortestPath((ms)-[r:Follow]-(cs)) RETURN p;
MATCH (a:Person { name:'Node A' })-[r]->(b:Person { name:'Node B' })
RETURN type(r);
MATCH (:Person { name:'Taylor' })-[r:Follow]->(Person)
RETURN Person.name;
请查看The Neo4j Cypher Manual v4.4
1.将关系模型映射到图数据库:
当从关系模型导出图模型时,您应该记住以下准则:
行是一个节点,表名是一个标签名,联接或外键是一种关系。
注意:Neo4j不存储空值。CSV文件中的Null或空字段可以跳过,或替换为加载CSV中的默认值。
例1:
CREATE (a:Place {id: 'A'}),
(b:Place {id: 'B'}),
(c:Place {id: 'C'}),
(d:Place {id: 'D'}),
(e:Place {id: 'E'}),
(f:Place {id: 'F'}),
(g:Place {id: 'G'}),
(d)-[:LINK {cost:4}]->(b),
(d)-[:LINK {cost:6}]->(e),
(b)-[:LINK {cost:1}]->(a),
(b)-[:LINK {cost:3}]->(c),
(a)-[:LINK {cost:2}]->(c),
(c)-[:LINK {cost:5}]->(e),
(e)-[:LINK {cost:10}]->(c),
(f)-[:LINK {cost:1}]->(g);
#s = '({0}) - [:LINK cost:{1}] -> ({2})'.format('a',10, 'c')
CREATE(Shanghai:City{name:'上海'}),
(Suzhou:City{name:'苏州'}),
(Wuxi:City{name:'无锡'}),
(Nanjing:City{name:'南京'}),
(Ningbo:City{name:'宁波'}),
(Shanghai)-[:Neighbor {distance:80}]->(Suzhou),
(Shanghai)-[:Neighbor {distance:120}]->(Wuxi),
(Shanghai)-[:Neighbor {distance:300}]->(Nanjing) ,
(Shanghai)-[:Neighbor {distance:250}]->(Ningbo);
//无权重:
CREATE (Shanghai)-[:Neighbor]->(Suzhou) CREATE (Shanghai)-[:Neighbor]->(Wuxi) CREATE (Shanghai)-[:Neighbor]->(Nanjing) CREATE (Shanghai)-[:Neighbor]->(Ningbo)
//加权重:
CREATE (Shanghai)-[:Neighbor {distance:80}]->(Suzhou) CREATE (Shanghai)-[:Neighbor {distance:120}]->(Wuxi) CREATE (Shanghai)-[:Neighbor {distance:300}]->(Nanjing) CREATE (Shanghai)-[:Neighbor {distance:250}]->(Ningbo)
1.问题
qid的数据不可能一条一条的创建,需要通过csv文件导入,那么导入时的cost(也就是边的次数)怎么写进去?
2.目前进展
加载csv文件,导入节点数据(不带权重)
LOAD CSV WITH HEADERS FROM 'file:///question.csv' AS row MERGE (question:Question{qID:row.qID}) ON CREATE SET question.qName=row.qName;
或者
LOAD CSV WITH HEADERS FROM 'file:///qid_qname.csv' AS row MERGE (question:Question{qName:row.qName}) ON CREATE SET question.qID=row.qID;
查看节点数据
MATCH(q:Question) return q LIMIT 10;
后面涉及项目内部,不再举例
执行此代码块以在数据库中创建订单节点:
// Create orders
LOAD CSV WITH HEADERS FROM 'https://gist.githubusercontent.com/jexp/054bc6baf36604061bf407aa8cd08608/raw/8bdd36dfc88381995e6823ff3f419b5a0cb8ac4f/orders.csv' AS row
MERGE (order:Order {orderID: row.OrderID})
ON CREATE SET order.shipName = row.ShipName;
如果已将CSV文件放入import folder,则应使用以下代码语法从本地目录加载CSV文件:
// Create orders
LOAD CSV WITH HEADERS FROM 'file:///orders.csv' AS row
MERGE (order:Order {orderID: row.OrderID})
ON CREATE SET order.shipName = row.ShipName;
这段代码在数据库中创建830个订单节点。
通过执行以下代码,可以查看数据库中的一些节点:
MATCH (o:Order) return o LIMIT 5;
执行此代码块以在数据库中创建产品节点:
// Create products
LOAD CSV WITH HEADERS FROM 'https://gist.githubusercontent.com/jexp/054bc6baf36604061bf407aa8cd08608/raw/8bdd36dfc88381995e6823ff3f419b5a0cb8ac4f/products.csv' AS row
MERGE (product:Product {productID: row.ProductID})
ON CREATE SET product.productName = row.ProductName, product.unitPrice = toFloat(row.UnitPrice);
这段代码在数据库中创建77个产品节点。
通过执行以下代码,可以查看数据库中的一些节点:
MATCH (p:Product) return p LIMIT 5;
执行此代码块以在数据库中创建供应商节点:
// Create suppliers
LOAD CSV WITH HEADERS FROM 'https://gist.githubusercontent.com/jexp/054bc6baf36604061bf407aa8cd08608/raw/8bdd36dfc88381995e6823ff3f419b5a0cb8ac4f/suppliers.csv' AS row
MERGE (supplier:Supplier {supplierID: row.SupplierID})
ON CREATE SET supplier.companyName = row.CompanyName;
这段代码在数据库中创建29个供应商节点。
通过执行以下代码,可以查看数据库中的一些节点:
MATCH (s:Supplier) return s LIMIT 5;
执行此代码块以在数据库中创建员工节点:
// Create employees
LOAD CSV WITH HEADERS FROM 'https://gist.githubusercontent.com/jexp/054bc6baf36604061bf407aa8cd08608/raw/8bdd36dfc88381995e6823ff3f419b5a0cb8ac4f/employees.csv' AS row
MERGE (e:Employee {employeeID:row.EmployeeID})
ON CREATE SET e.firstName = row.FirstName, e.lastName = row.LastName, e.title = row.Title;
这段代码在数据库中创建9个员工节点。
通过执行以下代码,可以查看数据库中的一些节点:
MATCH (e:Employee) return e LIMIT 5;
// Create categories
LOAD CSV WITH HEADERS FROM 'https://gist.githubusercontent.com/jexp/054bc6baf36604061bf407aa8cd08608/raw/8bdd36dfc88381995e6823ff3f419b5a0cb8ac4f/categories.csv' AS row
MERGE (c:Category {categoryID: row.CategoryID})
ON CREATE SET c.categoryName = row.CategoryName, c.description = row.Description;
这段代码在数据库中创建8个分类节点。
通过执行以下代码,可以查看数据库中的一些节点:
MATCH (c:Category) return c LIMIT 5;
先执行下列代码来 Create relationships between orders and products
// Create relationships between orders and products
LOAD CSV WITH HEADERS FROM 'https://gist.githubusercontent.com/jexp/054bc6baf36604061bf407aa8cd08608/raw/8bdd36dfc88381995e6823ff3f419b5a0cb8ac4f/orders.csv' AS row
MATCH (order:Order {orderID: row.OrderID})
MATCH (product:Product {productID: row.ProductID})
MERGE (order)-[op:CONTAINS]->(product)
ON CREATE SET op.unitPrice = toFloat(row.UnitPrice), op.quantity = toFloat(row.Quantity);
这段代码在数据库中创建2155个关系。
通过执行以下代码,可以查看数据库中的这些关系:
MATCH (o:Order)-[]-(p:Product)
RETURN o,p LIMIT 10;
部分图展示如下:
再执行下列代码来 Create relationships between orders and employees
// Create relationships between orders and employees
LOAD CSV WITH HEADERS FROM 'https://gist.githubusercontent.com/jexp/054bc6baf36604061bf407aa8cd08608/raw/8bdd36dfc88381995e6823ff3f419b5a0cb8ac4f/orders.csv' AS row
MATCH (order:Order {orderID: row.OrderID})
MATCH (employee:Employee {employeeID: row.EmployeeID})
MERGE (employee)-[:SOLD]->(order);
这段代码在数据库中创建830个关系。
通过执行以下代码,可以查看数据库中的这些关系:
MATCH (o:Order)-[]-(e:Employee)
RETURN o,e LIMIT 10;
// Create relationships between products and suppliers
LOAD CSV WITH HEADERS FROM 'https://gist.githubusercontent.com/jexp/054bc6baf36604061bf407aa8cd08608/raw/8bdd36dfc88381995e6823ff3f419b5a0cb8ac4f/products.csv
' AS row
MATCH (product:Product {productID: row.ProductID})
MATCH (supplier:Supplier {supplierID: row.SupplierID})
MERGE (supplier)-[:SUPPLIES]->(product);
这段代码在数据库中创建77个关系。
通过执行以下代码,可以查看数据库中的这些关系:
MATCH (s:Supplier)-[]-(p:Product)
RETURN s,p LIMIT 10;
// Create relationships between products and categories
LOAD CSV WITH HEADERS FROM 'https://gist.githubusercontent.com/jexp/054bc6baf36604061bf407aa8cd08608/raw/8bdd36dfc88381995e6823ff3f419b5a0cb8ac4f/products.csv
' AS row
MATCH (product:Product {productID: row.ProductID})
MATCH (category:Category {categoryID: row.CategoryID})
MERGE (product)-[:PART_OF]->(category);
这段代码在数据库中创建77个关系。
通过执行以下代码,可以查看数据库中的这些关系:
MATCH (c:Category)-[]-(p:Product)
RETURN c,p LIMIT 10;
// Create relationships between employees (reporting hierarchy)
LOAD CSV WITH HEADERS FROM 'https://gist.githubusercontent.com/jexp/054bc6baf36604061bf407aa8cd08608/raw/8bdd36dfc88381995e6823ff3f419b5a0cb8ac4f/employees.csv' AS row
MATCH (employee:Employee {employeeID: row.EmployeeID})
MATCH (manager:Employee {employeeID: row.ReportsTo})
MERGE (employee)-[:REPORTS_TO]->(manager);
这段代码在数据库中创建8个关系。
通过执行以下代码,可以查看数据库中的这些关系:
MATCH (e1:Employee)-[]-(e2:Employee)
RETURN e1,e2 LIMIT 10;
MATCH (e:Employee)-[rel:SOLD]->(o:Order)-[rel2:CONTAINS]->(p:Product)
RETURN e, rel, o, rel2, p LIMIT 25;
MATCH (s:Supplier)-[r1:SUPPLIES]->(p:Product {productName: 'Chocolade'})-[r2:PART_OF]->(c:Category)
RETURN s, r1, p, r2, c;
MATCH (choc:Product {productName:'Chocolade'})<-[:CONTAINS]-(:Order)<-[:SOLD]-(employee),
(employee)-[:SOLD]->(o2)-[:CONTAINS]->(other:Product)
RETURN employee.employeeID as employee, other.productName as otherProduct, count(distinct o2) as count
ORDER BY count DESC
LIMIT 5;
MATCH (e:Employee)<-[:REPORTS_TO]-(sub)
RETURN e.employeeID AS manager, sub.employeeID AS employee;
MATCH path = (e:Employee)<-[:REPORTS_TO*]-(sub)
WITH e, sub, [person in NODES(path) | person.employeeID][1..-1] AS path
RETURN e.employeeID AS manager, path as middleManager, sub.employeeID AS employee
ORDER BY size(path);
MATCH (e:Employee)
OPTIONAL MATCH (e)<-[:REPORTS_TO*0..]-(sub)-[:SOLD]->(order)
RETURN e.employeeID as employee, [x IN COLLECT(DISTINCT sub.employeeID) WHERE x <> e.employeeID] AS reportsTo, COUNT(distinct order) AS totalOrders
ORDER BY totalOrders DESC;
Neo4j学习链接: