我正在开发一个应用程序,它将允许用户根据可用的在线课程推荐学习路径:
在我当前的模型中,序列是不同的节点。它们标记了用户创建的学习路径的起点,并包含有关序列的其他有用的元数据(例如:知识领域,用户评分等)
然后,我们使用NEXT关系浏览用户定义的序列可能包含的所有课程。
单个课程可能是许多不同的用户创建的序列的一部分,因此两个课程节点之间可能存在任意数量的NEXT关系,并且每个关系都将父序列的ID作为属性。
这意味着在获取序列时,dbms将需要遵循与特定path_id匹配的NEXT关系,以便检索与该课程关联的所有课程节点。
我从不同的来源了解到,使用关系属性浏览图形是一种反模式,因为它会导致对多个关系的I / O访问。
我只希望序列最长大约20至30个课程。另一方面,我希望获取整个序列将是应用程序中非常常见的操作。
我的问题是:这里的反模式是否合理,或者有更好的方法吗?
答案 0 :(得分:1)
您可以添加引用CourseRef
节点的新节点(标记为Course
),其中CourseRef
节点通过NEXT
关系链接在一起( t存储序列ID)。每个Sequence
节点都将引用链中的第一个CourseRef
。这样,Course
节点本身就不再需要链接在一起了。
这可能是新的数据模型:
(:User)-[:SUBSCRIBED_TO]->(:Sequence)
(:Sequence)-[:STARTS_AT]->(:CourseRef)
(:Course)<-[:REFERS_TO]-(:CourseRef)-[:NEXT]->(:CourseRef)
(:Course)-[:REQUIRED_BY]->(:Course)
使用上述数据模型,您可以通过以下方式为Course
中的每个Sequence
获取所有User
路径(如您的示例,可以有多个路径):
MATCH (u:User {id: 123})-[:SUBSCRIBED_TO]->(seq)-[:STARTS_AT]->(r1)
MATCH path = (r1)-[:NEXT*0..]->(r2)
WHERE SIZE((r2)-[:NEXT]->()) = 0
UNWIND NODES(path) AS ref
MATCH (ref)-[:REFERS_TO]-(course)
RETURN u, seq.id AS seqId, COLLECT(course) AS courses
WHERE
子句对r2
进行了快速度检查,以确保它是路径中的叶子Course
。