Neo4j的介紹可以參考這篇文章:《知識圖譜技術(shù)與應(yīng)用指南(轉(zhuǎn))》
其實冯勉,Python操作Neo4j舷嗡,既可以用neo4j
也可以用py2neo
毁腿,前者是Neo4j官方的api汰蜘,但是py2neo
開發(fā)地更早仇冯,已經(jīng)到V4了。
官方文檔地址:https://py2neo.org/v4/
0族操、安裝
下載Neo4j:https://neo4j.com/download/
使用pip安裝: pip install py2neo
從github源碼安裝:pip install git+https://github.com/technige/py2neo.git#egg=py2neo
1苛坚、數(shù)據(jù)類型
1.1 節(jié)點(diǎn)Node
和關(guān)系Relationship
對象
圖數(shù)據(jù)庫,最重要的就是節(jié)點(diǎn)色难、邊和屬性泼舱,py2neo
中最重要的就是類Node
和Relationship
:
from py2neo.data import Node, Relationship
a = Node("Person", name="Alice")
b = Node("Person", name="Bob")
ab = Relationship(a, "KNOWS", b)
print(ab)
# (Alice)-[:KNOWS]->(Bob)
如果沒有指定節(jié)點(diǎn)之間的關(guān)系,則默認(rèn)為TO
枷莉。也可以自建類Relationship
的子類娇昙,如下:
c = Node("Person", name="Carol")
class WorksWith(Relationship): pass
ac = WorksWith(a, c)
print(type(ac))
# 'WORKS_WITH'
1.2 子圖Subgraph
對象
集合操作是創(chuàng)建子圖最簡便的方法:
s = ab | ac
print(s)
# {(alice:Person {name:"Alice"}), (bob:Person {name:"Bob"}), (carol:Person {name:"Carol"}), (Alice)-[:KNOWS]->(Bob), (Alice)-[:WORKS_WITH]->(Carol)}
print(s.nodes())
# frozenset({(alice:Person {name:"Alice"}), (bob:Person {name:"Bob"}), (carol:Person {name:"Carol"})})
print(s.relationships())
# frozenset({(Alice)-[:KNOWS]->(Bob), (Alice)-[:WORKS_WITH]->(Carol)})
1.3 路徑Path
對象和可遍歷Walkable
類型
可遍歷對象是添加了遍歷信息的子圖。
w = ab + Relationship(b, "LIKES", c) + ac
print(w)
# (Alice)-[:KNOWS]->(Bob)-[:LIKES]->(Carol)<-[:WORKS_WITH]-(Alice)
1.4 記錄Record
對象
Record
對象是值的有序有鍵的集合笤妙,和具名元組很像冒掌。
1.5 表格Table
對象
Table
對象是包含Record
對象的列表。
2 圖數(shù)據(jù)庫
Graph
對象是最重要的和Neo4j交互的類蹲盘。
from py2neo import Graph
graph = Graph(password="password")
print(graph.run("UNWIND range(1, 3) AS n RETURN n, n * n as n_sq").to_table())
# n | n_sq
# -----|------
# 1 | 1
# 2 | 4
# 3 | 9
2.1 數(shù)據(jù)庫Database
類
用于連接圖數(shù)據(jù)庫
from py2neo import Database
db = Database("bolt://camelot.example.com:7687")
默認(rèn)值是bolt://localhost:7687
default_db = Database()
>>> default_db
<Database uri='bolt://localhost:7687'>
2.2 圖Graph
Graph
類表示Neo4j中的圖數(shù)據(jù)存儲空間股毫。
>>> from py2neo import Graph
>>> graph_1 = Graph()
>>> graph_2 = Graph(host="localhost")
>>> graph_3 = Graph("bolt://localhost:7687")
match
匹配:
for rel in graph.match((alice, ), r_type="FRIEND"):
print(rel.end_node["name"])
merge
融合:
>>> from py2neo import Graph, Node, Relationship
>>> g = Graph()
>>> a = Node("Person", name="Alice", age=33)
>>> b = Node("Person", name="Bob", age=44)
>>> KNOWS = Relationship.type("KNOWS")
>>> g.merge(KNOWS(a, b), "Person", "name")
再創(chuàng)建第三個節(jié)點(diǎn):
>>> c = Node("Company", name="ACME")
>>> c.__primarylabel__ = "Company"
>>> c.__primarykey__ = "name"
>>> WORKS_FOR = Relationship.type("WORKS_FOR")
>>> g.merge(WORKS_FOR(a, c) | WORKS_FOR(b, c))
nodes
方法,找到所有符合條件的節(jié)點(diǎn):
>>> graph = Graph()
>>> graph.nodes[1234]
(_1234:Person {name: 'Alice'})
>>> graph.nodes.get(1234)
(_1234:Person {name: 'Alice'})
>>> graph.nodes.match("Person", name="Alice").first()
(_1234:Person {name: 'Alice'})
2.3 事務(wù)Transactions
commit()
提交事務(wù)
create(subgraph)
創(chuàng)建節(jié)點(diǎn)和關(guān)系
>>> from py2neo import Graph, Node, Relationship
>>> g = Graph()
>>> tx = g.begin()
>>> a = Node("Person", name="Alice")
>>> tx.create(a)
>>> b = Node("Person", name="Bob")
>>> ab = Relationship(a, "KNOWS", b)
>>> tx.create(ab)
>>> tx.commit()
>>> g.exists(ab)
True
2.4 查詢結(jié)果
Cursor
類
前進(jìn)一個節(jié)點(diǎn)召衔,打印節(jié)點(diǎn)的名字:
while cursor.forward():
print(cursor.current["name"])
因為Cursor是可迭代對象铃诬,也可以這樣:
for record in cursor:
print(record["name"])
只關(guān)心一個節(jié)點(diǎn),則:
if cursor.forward():
print(cursor.current["name"])
或:
print(next(cursor)["name"])
從單條記錄只返回一個值:
print(cursor.evaluate())
data()
苍凛,提取出所有數(shù)據(jù):
>>> from py2neo import Graph
>>> graph = Graph()
>>> graph.run("MATCH (a:Person) RETURN a.name, a.born LIMIT 4").data()
[{'a.born': 1964, 'a.name': 'Keanu Reeves'},
{'a.born': 1967, 'a.name': 'Carrie-Anne Moss'},
{'a.born': 1961, 'a.name': 'Laurence Fishburne'},
{'a.born': 1960, 'a.name': 'Hugo Weaving'}]
evaluate(field=0)
趣席,從下條記錄返回第一個字段:
>>> from py2neo import Graph
>>> g = Graph()
>>> g.run("MATCH (a) WHERE a.email={x} RETURN a.name", x="bob@acme.com").evaluate()
'Bob Robertson'
stats()
,返回查詢統(tǒng)計:
>>> from py2neo import Graph
>>> g = Graph()
>>> g.run("CREATE (a:Person) SET a.name = 'Alice'").stats()
constraints_added: 0
constraints_removed: 0
contained_updates: True
indexes_added: 0
indexes_removed: 0
labels_added: 1
labels_removed: 0
nodes_created: 1
nodes_deleted: 0
properties_set: 1
relationships_created: 0
relationships_deleted: 0
to_data_frame(index=None, columns=None, dtype=None)
毫深,將數(shù)據(jù)返回為pandas的DataFrame:
>>> from py2neo import Graph
>>> graph = Graph()
>>> graph.run("MATCH (a:Person) RETURN a.name, a.born LIMIT 4").to_data_frame()
a.born a.name
0 1964 Keanu Reeves
1 1967 Carrie-Anne Moss
2 1961 Laurence Fishburne
3 1960 Hugo Weaving
3 py2neo.matching
– 實體匹配
3.1 節(jié)點(diǎn)匹配
使用NodeMatcher
匹配節(jié)點(diǎn):
>>> from py2neo import Graph, NodeMatcher
>>> graph = Graph()
>>> matcher = NodeMatcher(graph)
>>> matcher.match("Person", name="Keanu Reeves").first()
(_224:Person {born:1964,name:"Keanu Reeves"})
使用where
子句匹配:
>>> list(matcher.match("Person").where("_.name =~ 'K.*'"))
[(_57:Person {born: 1957, name: 'Kelly McGillis'}),
(_80:Person {born: 1958, name: 'Kevin Bacon'}),
(_83:Person {born: 1962, name: 'Kelly Preston'}),
(_224:Person {born: 1964, name: 'Keanu Reeves'}),
(_226:Person {born: 1966, name: 'Kiefer Sutherland'}),
(_243:Person {born: 1957, name: 'Kevin Pollak'})]
排序order_by()
和數(shù)量limit()
限制:
>>> list(matcher.match("Person").where("_.name =~ 'K.*'").order_by("_.name").limit(3))
[(_224:Person {born: 1964, name: 'Keanu Reeves'}),
(_57:Person {born: 1957, name: 'Kelly McGillis'}),
(_83:Person {born: 1962, name: 'Kelly Preston'})]
只統(tǒng)計數(shù)量吩坝,用len():
>>> len(matcher.match("Person").where("_.name =~ 'K.*'"))
6
3.2 關(guān)系匹配RelationshipMatcher
使用的方法和節(jié)點(diǎn)匹配很相似:
first()
order_by(*fields)
where(*conditions, **properties)
4 對象圖映射Object-Graph Mapping
用于綁定Python對象和底層圖數(shù)據(jù)
class Movie(GraphObject):
__primarykey__ = "title"
title = Property()
tag_line = Property("tagline")
released = Property()
actors = RelatedFrom("Person", "ACTED_IN")
directors = RelatedFrom("Person", "DIRECTED")
producers = RelatedFrom("Person", "PRODUCED")
class Person(GraphObject):
__primarykey__ = "name"
name = Property()
born = Property()
acted_in = RelatedTo(Movie)
directed = RelatedTo(Movie)
produced = RelatedTo(Movie)
4.1 圖對象
GraphObject
,用作基類
4.2 屬性Property()
>>> class Person(GraphObject):
... name = Property()
...
>>> alice = Person()
>>> alice.name = "Alice Smith"
>>> alice.name
"Alice Smith"
4.3 標(biāo)簽Label()
標(biāo)簽是布爾值哑蔫,默認(rèn)是False
>>> class Food(GraphObject):
... hot = Label()
...
>>> pizza = Food()
>>> pizza.hot
False
>>> pizza.hot = True
>>> pizza.hot
True
4.4 關(guān)聯(lián)對象
class Person(GraphObject):
__primarykey__ = "name"
name = Property()
likes = RelatedTo("Person")
for friend in person.likes:
print(friend.name)
4.5 對象匹配
>>> Person.match(graph, "Keanu Reeves").first()
<Person name='Keanu Reeves'>
>>> list(Person.match(graph).where("_.name =~ 'K.*'"))
[<Person name='Keanu Reeves'>,
<Person name='Kevin Bacon'>,
<Person name='Kiefer Sutherland'>,
<Person name='Kevin Pollak'>,
<Person name='Kelly McGillis'>,
<Person name='Kelly Preston'>]
4.6 對象操作
>>> alice = Person()
>>> alice.name = "Alice Smith"
>>> graph.push(alice)
>>> alice.__node__
(_123:Person {name: 'Alice Smith'})