Giter Site home page Giter Site logo

Comments (17)

robinedwards avatar robinedwards commented on July 26, 2024

Hey thanks :)

I was hoping to add support for this. I think the best way is to update the current RelationshipManager class to support it.

Do you have any thoughts on how the api would look? We could specify the properties during connect?

class Person(StructuredNode):
    lived_in = RelationshipTo('LIVED_IN', 'Town')

bristol = Town(..)
jim = Person(...)
jim.lived_in.connect(bristol, {'from': 123434, 'to': 23423})

As far a search goes we could either add a separate method to RelationshipManager maybe 'search_by_rel' or we could extend the existing search method to provide rel properties.

There currently isn't the concept of a relationship object in neomodel... it's probably about time I added one.

R

from neomodel.

opqopq avatar opqopq commented on July 26, 2024

Actually, since you went through all the effort to define ORM for Node, I'd think it would be even easier to re-use it for Relationship.

Something like this:

class MyRel(RelationShipTo):#OR maybe just deriving from RelationShip)
....name=StringProperty()
....size=IntegrerProperty()
....reltype="FRIEND" #??? either here, or in the __call function, passed below
....Direction="OUTGOING"# Again, may not be used if deriving from RelationShipTo

class OneNode(StructuredNode):
....pass

class MyNode(StructuredNode):
....name=StringProperty()
....other= MyRel('OneNode','FRIEND)

What do you think ?

Sorry, I do no know the format/way to insert code in these comments...

from neomodel.

opqopq avatar opqopq commented on July 26, 2024

Also, no matter how you define this, but there should be a way to retrieve & update these informations after creation time.
After looking tourhgh the code, it seems that, indeed, RelationshipManager is the way to go.
Then, it is just a matter of changing the usage of RelationShipTo/RelationShipFrom from function call to proper class usage.

from neomodel.

robinedwards avatar robinedwards commented on July 26, 2024

You can now create properties in a connect operation. Search support to come.

from neomodel.

bebbi avatar bebbi commented on July 26, 2024

Thanks for the great work! Looking forward to test neomodel more thoroughly.
On first sight (the README..), I'd like to second opqopqs request here.
It would be really nice to deal with the properties in the same structured manner as with nodes.
A example for this could be bulbflow.
There you have

class Person(Node)
    ...
    relates_to = Relationship('Person', 'Relation')

and

class Relation(Relationship)
    strength = StringProperty(default='low')
    start_date =
    type =
    ... all the relationship attributes....

If you had that in neomodel, the impact to the API could probably be minimal

rel = jim.relates_to.connect(john) # creates Relationship defaults such as "strength = 'low' "
rel.strength = 'high'
rel.save() # validate

The cool thing would be that you'd have the same level of validation on relationships as on nodes.
I love putting properties into relationships, I think there are many use-cases for this (like the above where the relation attributes are not attributes of the related persons) so it would be nice to make them "first class citizens".
What do you think?

from neomodel.

robinedwards avatar robinedwards commented on July 26, 2024

That's a good idea :)

Currently you can create properties via:

jim.knows.connect(john, {'since': 1365002257})

This allows us to do it in a single operation. returning the relation object on connect is a nice idea!

But as you mentioned this doesn't (currently) provide validation. How about something like this?

class Knows(StructuredRel):
    since=DateTimeProperty()

class Person(StructuredNode):
    name=StringProperty()
    knows=RelationshipTo('Person', 'KNOWS', rel_class='Knows')

jim = Person(name='Jim').save()
bob = Person(name='Bob').save()
jim.knows.connect(bob, {'since': datetime.utcnow()})

I don't think we should specify the relationship type on the relationship class as this prevents re-use of the rel class.

Any ideas on the api on retrieving the rels between two nodes?

R

from neomodel.

bebbi avatar bebbi commented on July 26, 2024

I don't think we should specify the relationship type on the relationship class as this prevents re-use of the rel class.

OK got it, there's of course a difference to node handling.
I don't see the need to make the relation class independent of the relationship type. The only reason I can construct is that the same relation class is associated with a different type when used between a different node class. Then your suggestion seems the simplest.

Any ideas on the api on retrieving the rels between two nodes?

My prevailing need is returning relations based on a node, followed by the need to filter and sort the resulting based on a relation attributes.
(I experience that relations of the same type originating from 1 node seem to often have a mutual relation, such as in 'among those I know, who do I know best' - therefore the sorting/filtering)

So, I think a new rel has to be returned on its creation. Also, finding a (filtered/sorted) set of edges from a node is important. I feel that rels = findrel(nodeA, nodeB) would be less important and could be derived from above. Would be interested in your thoughts about this.

Coming from bulbflows, the api is:
rels = node.outE(), or node.inE(), or node.bothE(). This is inspired by gremlin, the return value is a generator. They can be chained and filtered on type: node.outE('KNOWS').inE(). (where chaining is probably not a good idea if every call is a single cypher query roundtrip - but discussing this goes likely beyond my expertise.)

To adapt to your previous commands, maybe something like:
from_rels = germany.relationship_to('IS_FROM') ?

from neomodel.

robinedwards avatar robinedwards commented on July 26, 2024

Hmm it's a difficult one. I guess with nodes we inflate to objects based on their incoming category node relationship. We also name our category node and outgoing relationships via the class name of our node definition.

Should the relationship class and relationship type have the same kind of mapping?

I am just thinking if you have a large schema, you may end up with relationships of the same neo4j relationship 'type' but used in different contexts. i.e you may not want to share the same relationship class for all relationships of the same type.

Any particular reason you don't like specifying the class whilst defining the relationship on the node class?

Interesting you mention chaining and filtering based on relationship properties, there is a new feature in master allowing more advanced traversing. It's currently undocumented but if you check out my slides (towards the end).

https://github.com/robinedwards/slides/raw/master/sharehoods_skillsmatter.pdf

from neomodel.

robinedwards avatar robinedwards commented on July 26, 2024

@nigelsmall any thoughts on this?

from neomodel.

bebbi avatar bebbi commented on July 26, 2024

Traversal: here we go!! this is very cool.. now there's just a need to differentiate whether the return value is to be a rel or a node. The gremlin way's obviously something like node.outRels(type1).inNodes().inRels(type2) but any other thing with more focus on nodes could easily apply.
With your recent addition, how about something as simple as adding a function .return_rels() which returns the relations traversed between chain elements LAST and LAST-1?

Should the relationship class and relationship type have the same kind of mapping?

I think yes. I would propose a relation_category node. This looks more or less the same like a category node. Since from there you can't have a relation to a relation, you can use the relation type to index the node needed for validation. You may not even need an index, just follow the origin node -> 'category nodes' -> rel_category_node to find the validator. - Relating to this, I don't see a need for a requirement to "retrieve all relations of type X" because a relation seems to be of interest purely in the context of known nodes. (And technically, relations don't exist per se in neo4j anyway.)
If you wanted to separate rel class and type, another option would be a fixed property name in the relation class. That's similar to the bulbflow way - in bulbflow, there's

class Knows(Relationship):
    label = "knows"
    ...

graph.add_proxy("knows", Knows)

The API is then graph.knows.create(node1, node2), and the neo4j level rel type is "knows".

Any particular reason you don't like specifying the class whilst defining the relationship on the node class?

nothing really, except DRY if they're the same. (Specifying both the relation class and type in the node class seems to suggest doing both again in every node class that connects with the same relation type.)

from neomodel.

robinedwards avatar robinedwards commented on July 26, 2024

Yea I think something like return_rels() or just 'rels' would do the trick.

I think we need a word other than label as labels is a new feature being introduced in neo4j 2.0. You've sold me on putting the type in the class definition :)

class Knows(Relationship):
   __type__ = 'KNOWS'

Rel types with out a type definition can inflate directly to Relationship I guess.

from neomodel.

bebbi avatar bebbi commented on July 26, 2024

this looks beautiful! :)

from neomodel.

bebbi avatar bebbi commented on July 26, 2024

hey! how is this coming along, are you making any progress on this front? Unfortunately I'm not an expert coder, but if you give me clear pointers I might be able to help?

from neomodel.

robinedwards avatar robinedwards commented on July 26, 2024

I am hoping to get some time over the next few weeks to work on this.

I've been very busy at work on none neo stuff so haven't been able to
commit yet.

I am hoping to make a release to pypi soon which uses py2neo 1.5 (giving
python 3 support).

The next thing I look at will be relationship classes. However if you want
to give it a shot I am happy to provide pointers.

The first thing that comes to mind is the property mechanism is currently
tied to nodes, this needs abstracting slightly.

On 24 May 2013 20:30, bebbi [email protected] wrote:

hey! how is this coming along, are you making any progress on this front?
Unfortunately I'm not an expert coder, but if you give me clear pointers I
might be able to help?


Reply to this email directly or view it on GitHubhttps://github.com//issues/20#issuecomment-18425098
.

from neomodel.

robinedwards avatar robinedwards commented on July 26, 2024

Guys finally in master you will see support for relationship properties sorry for the delay and thanks for your patience.

I decided against inflating them purely by relationship type as it makes code a lot modular. You may also traverse relationships and filter by their properties (still experimental)

from neomodel.

gchorn avatar gchorn commented on July 26, 2024

@robinedwards I like that connect supports defining properties on the relationship being created. However, I have noticed that disconnect does not support filtering by properties to narrow down which relationship should be deleted.

As such, when I define multiple instances of a relationship type between two nodes, calling disconnect on that relationship type deletes all relationships between the two nodes, whereas what I really want is to select and delete only one specific relationship.

Is there any way to do this through the ORM that I've overlooked? I can't find it in the docs.

from neomodel.

robinedwards avatar robinedwards commented on July 26, 2024

Hi @gchorn there currently isn't but patches would be greatly appreciated. perhaps something like delete_where(**filters)?

from neomodel.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.