Neo4J 介绍、安装以及使用(附带示例)


Neo4J 介绍与安装

知识图谱由于其数据包含实体、属性、关系等,常见的关系型数据库诸如MySQL之类不能很好的体现数据的这些特点,因此知识图谱数据的存储一般是采用图数据库(Graph Databases)。而Neo4j是其中最为常见的图数据库。

  • 在Mac或者Linux中,安装好jdk后,直接解压下载好的Neo4J包,运行命令
  bin/neo4j start
  • windows系统下载好neo4j和jdk 1.8.0后,输入以下命令启动后neo4j
  neo4j.bat console

Neo4J 提供了一个用户友好的 Web 界面,可以进行各项配置、写入、查询等操作,并且提供了可视化功能。类似ElasticSearch一样,开箱即用的设计。

打开浏览器,输入http://127.0.0.1:7474/browser/

  • Cypher
  • 介绍:是Neo4J的声明式图形查询语言,允许用户不必编写图形结构的遍历代码,就可以对图形数据进行高效的查询。
  • 设计目的:类似SQL,适合于开发者以及在数据库上做点对点模式(ad-hoc)查询的专业操作人员。
  • 创建、更新、删除节点和关系
  • 通过模式匹配来查询和修改节点和关系 - 管理索引和约束等

Neo4J 增删查改

删除所有库

  MATCH (n) DETACH DELETE n

创建节点

  CREATE (n:Person {name:'John'}) RETURN n
  CREATE (n:Person {name:'Sally'}) RETURN n
  CREATE (n:Person {name:'Steve'}) RETURN n
  CREATE (n:Person {name:'Mike'}) RETURN n
  CREATE (n:Person {name:'Liz'}) RETURN n
  CREATE (n:Person {name:'Shawn'}) RETURN n

  CREATE (n:Location {city:'Miami', state:'FL'})
  CREATE (n:Location {city:'Boston', state:'MA'})
  CREATE (n:Location {city:'Lynn', state:'MA'})
  CREATE (n:Location {city:'Portland', state:'ME'})
  CREATE (n:Location {city:'San Francisco', state:'CA'})

创建关系

MATCH (a:Person {name:'Liz'}), 
        (b:Person {name:'Mike'}) 
  MERGE (a)-[:FRIENDS]->(b)

创建带属性的关系

MATCH (a:Person {name:'Shawn'}), 
        (b:Person {name:'Sally'}) 
  MERGE (a)-[:FRIENDS {since:2001}]->(b)


MATCH (a:Person {name:'Shawn'}), (b:Person {name:'John'}) MERGE (a)-[:FRIENDS {since:2012}]->(b)
  MATCH (a:Person {name:'Mike'}), (b:Person {name:'Shawn'}) MERGE (a)-[:FRIENDS {since:2006}]->(b)
  MATCH (a:Person {name:'Sally'}), (b:Person {name:'Steve'}) MERGE (a)-[:FRIENDS {since:2006}]->(b)
  MATCH (a:Person {name:'Liz'}), (b:Person {name:'John'}) MERGE (a)-[:MARRIED {since:1998}]->(b)


 MATCH (a:Person {name:'John'}), (b:Location {city:'Boston'}) MERGE (a)-[:BORN_IN {year:1978}]->(b)
  MATCH (a:Person {name:'Liz'}), (b:Location {city:'Boston'}) MERGE (a)-[:BORN_IN {year:1981}]->(b)
  MATCH (a:Person {name:'Mike'}), (b:Location {city:'San Francisco'}) MERGE (a)-[:BORN_IN {year:1960}]->(b)
  MATCH (a:Person {name:'Shawn'}), (b:Location {city:'Miami'}) MERGE (a)-[:BORN_IN {year:1960}]->(b)
  MATCH (a:Person {name:'Steve'}), (b:Location {city:'Lynn'}) MERGE (a)-[:BORN_IN {year:1970}]->(b)

查询

  MATCH (a:Person)-[:BORN_IN]->(b:Location {city:'Boston'}) RETURN a,b
查询所有对外带有关系的节点
  MATCH (a)--() RETURN a
查询所有对外带有关系的节点 以及关系类型
  MATCH (a)-[r]->() RETURN a.name, type(r)
查询特定关系
  MATCH (n)-[:MARRIED]-() RETURN n
查找某人的朋友的朋友
  MATCH (a:Person {name:'Mike'})-[r1:FRIENDS]-()-[r2:FRIENDS]-(friend_of_a_friend) RETURN friend_of_a_friend.name AS fofName

修改

增加/修改节点的属性
  MATCH (a:Person {name:'Liz'}) SET a.age=34
  MATCH (a:Person {name:'Shawn'}) SET a.age=32
  MATCH (a:Person {name:'John'}) SET a.age=44
  MATCH (a:Person {name:'Mike'}) SET a.age=25
删除节点的属性
MATCH (a:Person {name:'Mike'}) SET a.test='test'
MATCH (a:Person {name:'Mike'}) REMOVE a.test
删除节点
  MATCH (a:Location {city:'Portland'}) DELETE a
根据关系删除节点
  MATCH (a:Person {name:'Todd'})-[rel]-(b:Person) DELETE a,b,rel

Python 操作 Neo4j 图数据库

neo4j模块

# step 1:导入 Neo4j 驱动包
from neo4j import GraphDatabase
# step 2:连接 Neo4j 图数据库
driver = GraphDatabase.driver("bolt://localhost:7687", auth=("neo4j", "password"))
# 添加 关系 函数
def add_friend(tx, name, friend_name):
  tx.run("MERGE (a:Person {name: $name}) "
        "MERGE (a)-[:KNOWS]->(friend:Person {name: $friend_name})",
        name=name, friend_name=friend_name)
# 定义 关系函数
def print_friends(tx, name):
  for record in tx.run("MATCH (a:Person)-[:KNOWS]->(friend) WHERE a.name = $name "
                      "RETURN friend.name ORDER BY friend.name", name=name):
      print(record["friend.name"])
# step 3:运行
with driver.session() as session:
  session.write_transaction(add_friend, "Arthur", "Guinevere")
  session.write_transaction(add_friend, "Arthur", "Lancelot")
  session.write_transaction(add_friend, "Arthur", "Merlin")
  session.read_transaction(print_friends, "Arthur")

py2neo 模块

# step 1:导包
from py2neo import Graph, Node, Relationship
# step 2:构建图
g = Graph()
# step 3:创建节点
tx = g.begin()
a = Node("Person", name="Alice")
tx.create(a)
b = Node("Person", name="Bob")
# step 4:创建边
ab = Relationship(a, "KNOWS", b)
# step 5:运行
tx.create(ab)
tx.commit()

数据导入

neo4j-admin import

  1. csv分为两个nodes.csv和relations.csv
  # nodes.csv需要指定唯一ID和nam,
  headers = [
  'unique_id:ID', # 图数据库中节点存储的唯一标识
  'name', # 节点展示的名称
  'node_type:LABEL', # 节点的类型,比如Person和Location
  'property' # 节点的其他属性
  ]
 # relations.csv
  headers = [
  'unique_id', # 图数据库中关系存储的唯一标识
  'begin_node_id:START_ID', # begin_node和end_node的值来自于nodes.csv中节点
  'end_node_id:END_ID',
  'begin_node_name',
  'end_node_name',
  'begin_node_type',
  'end_node_type',
  'relation_type:TYPE', # 关系的类型,比如Friends和Married
  'property' # 关系的其他属性
  ]
  1. csv数据文件放在 neo4j安装绝对路径/import

  2. 指定neo4j使用哪个数据库

  修改 /root/neo4j/conf/neo4j.conf 文件中的 dbms.default_database=mygraph.db
  1. 重启neo4j

示例

  • 满足某种商品类型的所有品牌
MATCH p=(n:brand)-[:`品牌类别`]->(c:category)-[:`属于`]->(c1:category) where  c1.name='女装品牌' RETURN p LIMIT 25

image

  • 查询购买过某件商品的用户还买过其它什么商品
MATCH p=(u:user)-[:`购买`]->(g:product)<-[:`购买`]-(u1:user)-[:`购买`]->(g1:product) where g.pid='283721' RETURN p

image

  • 多关系查询 购买过 顺丰配送 真丝材质 上衣有哪些人 有哪些商品
MATCH p=(u:user)-[:`购买`]->(g:product)-[:`品类`|:`材质`|:`配送`]->(c) where c.name='上衣' or c.name='真丝' or c.name="顺丰" RETURN p

image

  • 购买了淑女装类型的人还买过什么商品
MATCH p=(g1:product)<--(u:user)-[:`购买`]->(g:product)-[:`品类`|:`材质`|:`配送`|:`风格`]->(c) where c.name='淑女' RETURN p

image

  • 咨询了某个商家(点击了某个商品)的人还买过什么商品(品类、材质、配送)
MATCH p=(s{sid:'123'})<-[:`咨询`]-(u:user)-[:`购买`]->(g:product)-[:`品类`|:`材质`|:`配送`]->(c)  RETURN p 

image