0
votes

Below, a conceptual example of my context:

I have an abstract class named: User (containing an id property as String)
I have a User subclass named: FacebookUser
I have a User subclass named: TwitterUser

Using Spring-Data-Neo4j, I make User a @NodeEntity.

I create a test class in order to insert a FacebookUser and a TwitterUser in the graph.
The whole well occurs => both nodes are inserted and have a _type_ containing the fully qualified name of the subclass.
For instance: com.myApp.model.user.FacebookUser.

Now, I want to make this kind of cypher query:
Retrieve the User whose id = 123
Thus, I have to find the more efficient way to check for all user nodes (union of FacebookUsers and TwitterUser), in order to find the unique corresponding record.

I expected to find a way to tell to cypher something like this:
Take every index matching FacebookUser, every index matching TwitterUser, and check for the expected node amongst them

but I didn't manage.

My current query, working, is:

@Query("start u=node(*) where has(u.__type__) and u.__type__ =~ '.*User' and has(u.id) and u.id = {0} return u")

This one translates to:

Check for ALL nodes in the graph (I suppose, not efficient at all), then retain those ending with "User" (including FacebookUser and TwitterUser) and check for the right id

Is there a way to only use index nodes in this case, instead of scanning the whole graph?

I was thinking about a way to rename the _type_ property to the full qualified name of the parent class.

Can we do it easily with SDN?

Indeed, since it appears that SDN uses the Java class name associated to the node as the node's index name, it would allow to deal with only one index node for both Facebook and Twitter subtypes: the User index node.

1

1 Answers

1
votes

If you use @Indexed on the classes, you should get indexes like TwitterUser etc, that you then can use with your queries. However, there are limitations to the inheritance approach, see Spring Data Neo4j - Indexing and Inheritance for a related discussion.