Reputation: 15466
I'm creating a simple social graph where a user can create a post, tag it, and comment on it. I'm using py2neo to do the modelling. The model has user
and post
as nodes. A user TAGGED
, POSTED
, or COMMENTED
on a post
. In my case, a single user can create multiple tag
s or comment
s on a single post
(just like any social network out there). Based on my model, this necessitates multiple TAGGED
or COMMENTED
relationships but with distinct properties. The model is built thusly:
from py2neo.ogm import (
GraphObject,
Property,
RelatedTo,
RelatedFrom
)
class User(GraphObject):
__primarykey__ = 'name'
name = Property()
posts = RelatedTo('Post', 'POSTED')
comments = RelatedTo('Post', 'COMMENTED')
tags = RelatedTo('Post', 'TAGGED')
def __init__(self, name):
self.name = name
class Post(GraphObject):
# assumes __id__ as primary key because
# left undefined
title = Property()
users = RelatedFrom('User', 'POSTED')
comments = RelatedFrom('User', 'COMMENTED')
tags = RelatedFrom('User', 'TAGGED')
def __init__(self, title):
self.title = title
I run the following to build the graph:
user = User(name='john')
post = Post(title='Wow!')
user.posts.add(
post,
{'date': '2017-04-26'}
)
graph.push(user)
user.comments.add(
post,
{'caption': 'I know!', 'date': '2017-04-26'}
)
graph.push(user)
for tag in ['yellow', 'green']:
user.tags.add(
post,
{'tag': tag, 'date': '2017-04-26'}
)
graph.push(user)
I would expect there to be two TAGGED
relationships, something like this:
But I see this is not the case:
My question then is twofold. (1) Can create a multiple relationships of the same type with different properties? (2) Is this the best model choice for the use case?
Upvotes: 0
Views: 973
Reputation: 51
You can use neo4jrestclient. It alows you to have multiple relationships of the same type and it's quite easy to use too. You can use the following code:
from neo4jrestclient.client import GraphDatabase
gdb=GraphDatabase("http://localhost:7474/db/data/")
user=gdb.nodes.create(name='john')
post=gdb.nodes.create(title='wow')
user.labels.add('User')
post.labels.add('Post')
u=gdb.labels.get('User')
p=gdb.labels.get('Post')
now for multiple relationships
for tag in ['yellow', 'green']:
u.get(name='john')[0].relationships.create('TAGGED',p.get(id=0)[0],tag=tag,date='2017-04-26')
this should do it. The .get is used to update a node much like .push. And there can be much cleaner way to do this, but you get the idea. The documentation is pretty decent too. https://readthedocs.org/projects/neo4j-rest-client/downloads/pdf/latest/
Upvotes: 1
Reputation: 66967
Although neo4j (and most programming interfaces to neo4j, like Cypher) does support multiple relationships of the same type (with possibly differing property sets) between a single pair of nodes, py2neo
does not seem to (see this issue).
I suggest that you consider using some other way to use neo4j from Python, like the officially supported neo4j Python Driver.
Upvotes: 0