[英]py2neo ogm Relationship with Multiple Node Labels
我想使用py2neo的OGM來表示從一種節點類型到兩種節點類型的關系。
我有一個解決方案(下面)只適用於存儲數據庫中的節點/關系,我找不到一個在檢索關系時正常工作的解決方案。
這是我的榜樣。 考慮從人到汽車的OWNS關系:
from py2neo.ogm import GraphObject, Property, RelatedTo
from py2neo import Graph
class Person(GraphObject):
name = Property()
Owns = RelatedTo("Car")
class Car(GraphObject):
model = Property()
g = Graph(host="localhost", user="neo4j", password="neo4j")
# Create Pete
p = Person()
p.name = "Pete"
# Create Ferrari
c = Car()
c.model = "Ferrari"
# Pete OWNS Ferrari
p.Owns.add(c)
# Store
g.push(p)
這很好用。 現在,讓我們假設一個人也擁有一個房子(這個代碼從上面的代碼繼續):
class House(GraphObject):
city = Property()
# Create House
h = House()
h.city = "New York"
# Pete OWNS House in New York
p.Owns.add(h)
# Update
g.push(p)
OWNS關系的“到”結束應該指向汽車,而不是房子。 但顯然py2neo並不關心那么多,並按照預期將所有內容存儲在數據庫中:通過OWNS關系連接的人員,汽車和房屋。
現在的問題是使用上面的類來檢索節點和關系。 正確加載節點屬性時,關系不是:
p = Person.select(g).where(name="Pete").first()
for n in list(p.Owns):
print type(n).__name__
這導致:
Car
Car
此行為與類對象一致。
如何在py2neo.ogm中使用相同的類建模“人OWNS汽車”和“人OWNS之家”? 我可以在這里使用任何已知的解決方案或解決方法嗎?
問題是“Owns”被設置為與“Car”節點的關系。 你需要建立另一種關系來擁有一所房子。 如果您希望關系在Neo4j中具有“OWNS”標簽,則需要填充RelatedTo函數的第二個變量。 這將在第3章的Py2Neo文檔( http://py2neo.org/v3/ )中介紹。
class Person(GraphObject):
name = Property()
OwnsCar = RelatedTo("Car", "OWNS")
OwnsHouse = RelatedTo("House" "OWNS")
class Car(GraphObject):
model = Property()
class House(GraphObject):
city = Property()
我想說Rick的答案解決了我試圖用Py2Neo OGM標記的問題。 謝謝里克!
我基本上有同樣的問題。 我無法找到答案,並嘗試使用py2neo和neomodel提出解決方案。
只是一個初學者
值得注意的是,我絕對不會回答這些作為這些庫中的任何一個庫的專家,而是作為有人試圖評估什么可能是開始一個簡單項目的最佳人。
最終結果
最終的結果是我在py2neo中找到了一個似乎有效的解決方法。 我也得到了neomodel的結果,我甚至更高興。 我最終對這兩個圖書館感到有些沮喪,但發現neomodel對新手來說更直觀。
資產標簽是答案權嗎?
我認為答案是創建一個“資產”標簽並將此標簽添加到House和Car並在Person和Asset之間創建[:OWNS]關系。 容易嗎? 不,顯然不是。 可能有一個簡單的答案,但我無法找到它。 我在py2neo中工作的唯一解決方案是下拉到庫的低級(而不是OGM)部分。
這是我在py2neo中所做的:
class Person(GraphObject):
name = Property()
class Car(GraphObject):
name = Property()
model = Property()
asset = Label("Asset")
class House(GraphObject):
name = Property()
city = Property()
asset = Label("Asset")
g = graph
# Create Pete
p = Person()
p.name = "Pete"
g.push(p)
# Create Ferrari
c = Car()
c.name = "Ferrari"
c.asset = True
g.push(c)
# Create House
h = House()
h.name = "White House"
h.city = "New York"
h.asset = True
g.push(h)
# Drop down a level and grab the actual nodes
pn = p.__ogm__.node
cn = c.__ogm__.node
# Pete OWNS Ferrari (lower level py2neo)
ap = Relationship(pn, "OWNS", cn)
g.create(ap)
# Pete OWNS House (lower level py2neo)
hn = h.__ogm__.node
ah = Relationship(pn, "OWNS", hn)
g.create(ah)
# Grab & Print
query = """MATCH (a:Person {name:'Pete'})-[:OWNS]->(n)
RETURN labels(n) as labels, n.name as name"""
data = g.data(query)
for asset in data:
print(asset)
這導致:
{'name': 'White House', 'labels': ['House', 'Asset']}
{'name': 'Ferrari', 'labels': ['Car', 'Asset']}
Neomodel版本
py2neo似乎用類名做一些巧妙的技巧來做它的魔法,而庫似乎從這個魔法中排除了標簽。 (我希望我錯了,但正如我所說,我無法解決它)。 我決定嘗試neomodel。
class Person(StructuredNode):
name = StringProperty(unique_index=True)
owns = RelationshipTo('Asset', 'OWNS')
likes = RelationshipTo('Car', "LIKES")
class Asset(StructuredNode):
__abstract_node__ = True
__label__ = "Asset"
name = StringProperty(unique_index=True)
class Car(Asset):
pass
class House(Asset):
city = StringProperty()
# Create Person, Car & House
pete = Person(name='Pete').save()
car = Car(name="Ferrari").save()
house = House(name="White House", city="Washington DC").save()
#Pete Likes Car
pete.likes.connect(car)
# Pete owns a House and Car
pete.owns.connect(house)
pete.owns.connect(car)
創建這些對象后,它們使用起來相對簡單:
for l in pete.likes.all():
print(l)
結果:
{'name': 'Ferrari', 'id': 385}
使用“抽象”關系,結果是該類型的對象,在本例中為Asset。
for n in pete.owns.all():
print(n)
print(type(n))
結果:
{'id': 389}
<class '__main__.Asset'>
似乎有一種方法可以將這些對象“膨脹”到所需類型,但我放棄了試圖將其想象成僅僅使用Cypher。 (感謝一些幫助理解這個...)
下降到Cypher級別,我們得到了我們想要的東西:
query = "MATCH (a:Person {name:'Pete'})-[:OWNS]->(n) RETURN n"
results, meta = db.cypher_query(query)
for n in results:
print(n)
結果:
[<Node id=388 labels={'Asset', 'Car'} properties={'name': 'Ferrari'}>]
[<Node id=389 labels={'Asset', 'House'} properties={'city': 'Washington DC', 'name': 'White House'}>]
結論
對於我想解決的許多問題,標簽的概念非常直觀。 我發現py2neo對標簽的處理令人困惑。 您的解決方法可能是下拉到py2neo的“較低級別”。 我個人認為neomodel語法更友好,建議檢查出來。 HTH。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.