Hi all!
I'm facing a performance issue on a rather small graph (~30K nodes and ~270K relationships).
I'm exposing the database through Spring Data Rest using spring 2.6.2, neo4j version: 4.4.2-community
The source code is freely available at Jedidex / public API · GitLab
For example, If I query the apparencies of a character, it can take up to 30 seconds to give a response. Meanwhile, if the same query get executed directly on the database it is almost instantaneous.
For reference, this is the Character model:
package com.holodex.publicapi.model.resource.character;
@Node("Character")
public class Character extends SWElement {
private String gender;
private Double height;
private Double mass;
private String hair;
private String eyes;
private String skin;
private String cyber;
@JsonSerialize(contentAs = SWElement.class)
@Relationship(type = "BORN_IN")
private SWElement homeWorld;
@JsonSerialize(contentAs = SWElement.class)
@Relationship(type = "OF_SPIECES")
private SWElement species;
@JsonSerialize(contentAs = SWElement.class)
@Relationship(type = "AFFILIATED_TO")
private Set<SWElement> affiliation;
@JsonSerialize(contentAs = SWElement.class)
@Relationship(type = "APPRENTICE_OF")
private Set<SWElement> masters;
@JsonSerialize(contentAs = SWElement.class)
@Relationship(type = "MASTER_OF")
private Set<SWElement> apprentices;
@JsonSerialize(contentAs = SWElement.class)
@Relationship(type = "APPEARS_IN")
private Set<SWElement> appears_in;
}
To keep things lightweight I expect each relationship to be of kind "SWElement" which is the supertype of every entity. It does not have any relationship.
An example of a result could be found here: https://api.jedidex.com/v1/characters/452217/appears_in, this returns ~350 elements which are the various media in which Luke Skywalker appears.
This request is performed by the following method in the Neo4jRepository:
package com.holodex.publicapi.repository.character;
@Override
@Query("MATCH path=(n:Character {element_id:$id})-[r]-(x) RETURN n, collect(nodes(path)), collect(relationships(path))")
Optional<Character> findById(Integer id);
The element_id property is indexed, I think is more of a object-mapping problem since the query is quite fast if executed on neo4j. I have no clue on how to optimize this case
I'm using Spring Rest Data since the goal is to have all the kinds of resources exposed by this API without writing too much of boilerplate code.
Thanks in advice
Niko