簡體   English   中英

py2neo ogm與多節點標簽的關系

[英]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標記的問題。 謝謝里克!

我基本上有同樣的問題。 我無法找到答案,並嘗試使用py2neoneomodel提出解決方案。

只是一個初學者

值得注意的是,我絕對不會回答這些作為這些庫中的任何一個庫的專家,而是作為有人試圖評估什么可能是開始一個簡單項目的最佳人。

最終結果

最終的結果是我在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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM