-
Notifications
You must be signed in to change notification settings - Fork 232
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Handling multiple labels where class inheritance is not appropriate #737
Comments
I've implemented a solution that works for my use case here: alanbuxton@cb51ba0 Happy to open a PR if you think helpful for the project |
This is interesting. I'll have to dive in more to fully understand the difference between this and using On the other hand, my worry would be that it can get confusing between abstract_node, optional_labels, inheritance ? |
If there is a neater solution using |
@alanbuxton A key (low level) detail in neomodel is that the labels are used to determine the class that a Node is "paired" with. Consequently, the labels are determined by the modelling choices. Neomodel returns the correct set of results because given the class hierarchy you described, Blue and Orange ARE ChildX objects too (where X \in {1,2}) I would like to suggest two things:
|
The data I've got in Neo4J was loaded from RDF via neosemantics. This tool gives all nodes a "Resource" label and can then create additional labels depending on their RDF "type". Each unique entity can have multiple types in RDF, and so can get multiple labels when loaded into Neo4J. In some rare cases, a node is treated as both a Person and an Organization. In some others I've got labels for both a SiteAddedActivity (meaning an organization opened in a new geographical location) and a ProductAddedActivity (meaning an organization has launched a new product). Here is a more realistic example showing the combined labels.
With this data the following both work:
and
both return:
But
throws a |
This is super clear ! You mentioned in your first post that
Here do you mean that your tested solution was something like this : class Organization(Resource):
__optional_labels__ = ["Person"]
pass ... and the "class name that is always created as a label" is Organization, which you don't want ? I'm not sure I understand why this doesn't fit the purpose, so if you could explain :-) |
Thanks for getting back so quickly @mariusconjeaud - really appreciate you looking into this. In this solution, every time something that has both
Because the combo of "Organization" and "Person" is already taken Really I want to be able to handle these cases. For a given node:
Thoughts? |
Any updates on this issue at all? I think the real solution would be if |
Hey @alanbuxton, sorry for letting that die down, I had less time to spend on neomodel recently, and most of it has been spent on the driver refactoring + py2neo becoming EOL for real - you'll hear more about this later. I now clearly understand what you want, but will admit to being lost for now, as I haven't worked on the cypher projection to objects yet so I know little about it. So to sump up, I still think this is important, I just did not have time, and it is not a trivial fix for me (yet) |
Not sure but think this is a related issue and wondering if it's a bug. In core.py the registry is created with this code; def build_class_registry(cls):
But if you look at it, it always doing a union. So in my case, I have 2 inherited classes...and as a result it's creating an index that looks like {"A","B"}, not {"A"}, {"B"} and {"A","B"} which is what I thought it was going to do. Then here in util.py is where its used:
The issue is that is always receiving just one of the classes, the one that was used to create the query that needs to be inflated. So either {"A"} or {"B"}, but not {"A", "B"} and the call fails with cannot resolve error because neither {"A"} or {"B"} is in the _NODE_CLASS_REGISTRY. It seems to be happening with all my inherits. Am I missing something? Was the intention to produce a list of all possible combinations, because I don't see how that code above accomplishes that, and as far as I see in my runs, frozen set only contains the multiple class index's. Thanks. |
This was initially raised as a question in the community forum: https://community.neo4j.com/t/how-to-handle-3-or-more-labels-in-neomodel/63767
Full details below:
I've got a Neo4J database where a node can have multiple labels.
As a toy example, imagine these nodes:
In neomodel I can define the following classes:
Using this I can do things like:
Child1.nodes.filter(name="Bar")
and get a result because the only matching node happens to have Child1 and Parent1 labels. But if I do
Child1.nodes.all()
the results also include nodes that are labelled withBlue
andOrange
so I get the following error:I can't simply do:
etc because in these cases I'd end up with a requirement for
BlueChild1
andOrangeChild1
as labels, which is not what I want in the database.This may sound like a contrived example but I'm seeing it in a real use case where a node could be an Organization or a Person or both (or even have some other labels), but it's not the case that Person or Organization inherit from each other.
I investigated using
__optional_labels__
but this is still problematic because the class name is always created as a label.The text was updated successfully, but these errors were encountered: