CONTEXT
我一直在开发一个由Neo4j数据库支持的spring boot网站。它旨在作为大学课程搜索系统。 (相关的结构是课程有模块组,有模块,与科目有关等......)
@JsonIdentityInfo(generator=JSOGGenerator.class)
public class Course extends DomainObject {
@NotNull private String name;
@NotNull private String courseCode;
private String description;
private School school;
@Convert(AttendanceTypeConverter.class)
private E_AttendanceType attendanceType;
@Convert(CourseTypeConverter.class)
private E_CourseType courseType;
@Convert(SandwichYearTypeConverter.class)
private E_SandwichYearType sandwichYearType;
@Relationship(type = "COURSE_DESCRIPTION_FOR", direction = Relationship.OUTGOING)
private Set<CourseYearDescription> courseYearDescription;
@Relationship(type = "COURSE_REQUISITES_SET_FOR", direction = Relationship.OUTGOING)
private Set<EntryRequirementsSet> entryRequirementsSets;
@Relationship(type = "RUNS_COURSE", direction = Relationship.OUTGOING)
Set<MemberOfFaculty> courseRunners;
对于课程页面,我需要填充课程的所有复杂字段,以便它们可以显示在页面上。我通过GraphRepository使用深度为4的T findOne(Long var1, int var2)
来获得一个综合的课程对象。我担心我的知识这是一个非常罕见的深度。但是,在运行该方法时,它返回时没有任何明显的延迟。
问题 在进行一些压力测试时,我将数据库中的课程数量增加到4000,并发现延迟呈指数增长。向后工作深度2最多20秒,3次约60秒,4次从未返回超过5分钟。尽管如此,所有3个先前都以毫秒为单位返回。
我发现这很奇怪,因为我正在构建单个课程节点(由长节点ID标识),因此增加的课程数量不应该以这种方式改变findOne方法的速度。它仍然会构建相同大小的对象。
测试
为了测试替代方案,我运行MATCH (course:Course{courseCode:'HG65'})-[*1..4]->(x)RETURN *
以查看需要多长时间(此处课程代码将查询限制为一个课程节点而不是节点ID)。它立即恢复了我想要的东西:
这让我觉得它可能与结果映射到GraphRepository中的POJO有关。为了测试我创建了一些映射函数,用于获取Neo4jOperation Result对象并通过解析+实例化/填充我的Course对象迭代结果图。在这个意义上,我将模仿深度为4的findOne。这没有延迟。 我唯一想到的是,findOne忽略了导致“course1 - &gt; school - &gt; course2”的关系方向,导致大量增加。虽然我现在不知道如何确认这种情况,也不知道如何绕过它。
问题
为什么当我添加更多课程对象时,findOne(ID,4)运行得如此之慢?每次我想要获取复杂的POJO时,如何在不编写定制查询和结果映射器的情况下克服此问题。
我应该采取其他方法吗?
答案 0 :(得分:0)
在检查了我的spring项目到Neo4j数据库的调用后,我确认了问题。 findOne()使用(n)-[]-(m)
关系。确切的查询如下:
MATCH (n) WITH n.nodeId = {id} MATCH p=(n)-[*0..4]- (m) RETURN p
这就是我的预期。如果我有10000个课程,这些课程都与一个深度的单个节点相关,那么它们将以2个深度相互匹配。 course -[]- school -[]- course
。这意味着任何其他与课程相关的查询都会以指数方式增加。
我的解决方案是更改默认查询并将其作为GraphRepository查询,如下所示:
MATCH (n:Course{courseCode:{courseCode}}) WITH n MATCH p=(n)-[*0..4]->(m) RETURN p
请注意,该关系已从双向更改为-[]->
向外方向。此解决方案与sping映射OGM完美配合,并且复杂POJO中的所有子类都按预期填充。