2016-09-02 12 views
1

py2neoのOGMを使用して、1つのノードタイプから2つのノードタイプへの関係を表現したいと思います。py2neo ogm複数ノードラベルとの関係

私はDB内のノード/リレーションシップを格納するためのソリューション(下記)があり、リレーションシップを取得するときに正しく動作するソリューションを見つけることができませんでした。

これは私の例です。人から車までの関係を考えてみましょう。

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) 

これはうまく機能します。さて、(このコードは上記1から続く)人が同様に家を所有していると仮定しましょう:

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) 

は関係の終わりは車ではなく、家を指すようになっている所有「すること」。しかし、明らかにpy2neoはそれほど気にせず、OWNSの関係を介して接続されたPerson、Car、HouseというDBにすべてを格納します。

問題は、上記のクラスを使用してノードとリレーションシップを取得することです。ノードのプロパティが正しくロードされているが、関係はありません。

Car 
Car 

この動作は、クラスオブジェクトと一致している:これは、その結果

p = Person.select(g).where(name="Pete").first() 
for n in list(p.Owns): 
    print type(n).__name__ 

py2neo.ogmに同じクラスの「Person OWNS Car」と「Person OWNS House」をどのようにモデル化できますか?ここで使用できる既知の解決策または回避策はありますか?

+0

strange。私は私のシステムで同じシナリオを複製しました。しかし、私にとっては、「車」の1行だけが印刷されました。 – dunder

+0

py2neo 3.1.1でもう一度チェックして、出力は元の質問と同じです。おそらく別のpy2neoバージョンですか?それでも、ここで私が指摘するのは、「カーハウス」の成果を達成したいということです。 –

答えて

0

私は本質的に同じ質問をしました。私は答えを見つけることができず、py2neoneomodelの両方を使ってこれに対する解決策を考え出しました。

ただ、初心者

私は間違いなくこれらのライブラリの1のいずれかの専門家としてではなく、開始するための最良のものが何であるかを評価しようとしている誰かとしてこれに答えるわけではないことに注意することが重要です簡単なプロジェクト。

最終結果

最終的な結果は、私が動作しているようpy2neoで回避策を見つけたことです。私はネモモデルでも結果が得られ、私はさらに幸せだった。私は両方の図書館に少し不満を抱いてしまいましたが、新人にとってより直感的なネオモデルを見つけました。

アセットラベルは回答権ですか?

「資産」ラベルを作成し、このラベルをハウスと車に追加し、PersonとAssetの間に[:OWNS]関係を作成すると答えました。簡単?いいえ、明らかにそうではありません。簡単な答えがあるかもしれませんが、私はそれを見つけることができませんでした。私がpy2neoで動作させる唯一の解決策は、ライブラリの下位レベル(OGMではなく)に落とすことでした。

は、ここで私はpy2neoにやったことだ:Neomodelバージョン

py2neoを行うために、クラス名といくつかの巧妙なトリックを行うようだ

{'name': 'White House', 'labels': ['House', 'Asset']} 
{'name': 'Ferrari', 'labels': ['Car', 'Asset']} 

:中

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) 

これは、結果その魔法とライブラリはこの魔法からラベルを除外しているようだ。 (私はこれについて間違っていることを望むが、私が言ったように、私はそれを解決することができませんでした)。私はネオモデルを試してみることにしました。これらのオブジェクトが作成された後

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} 

、この場合は資産。

for n in pete.owns.all(): 
    print(n) 
    print(type(n)) 

結果:

{'id': 389} 
<class '__main__.Asset'> 

希望のタイプにこれらのオブジェクトを「膨らませる」ための方法があるようですが、私はちょうどサイファーを使用しての賛成でそれを把握しようとあきらめました。 (いくつかの助けこれを理解いただければ幸いです...)サイファーレベルまで落とす

が、私たちは私たちが望む正確に何を得る:

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の「下位レベル」に落とされるかもしれません。私は個人的には、ネオモデルの構文がよりフレンドリーであり、それをチェックすることを提案していました。 HTH。

関連する問題