py2neo ogm与多节点标签的关系
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了py2neo ogm与多节点标签的关系相关的知识,希望对你有一定的参考价值。
我想使用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。
以上是关于py2neo ogm与多节点标签的关系的主要内容,如果未能解决你的问题,请参考以下文章