【问题标题】:Neo4 modeling: using relationship properties to navigate graph - antipattern alternativesNeo4 建模:使用关系属性来导航图 - 反模式替代方案
【发布时间】:2019-08-05 18:44:13
【问题描述】:

我正在开发一个应用程序,它允许用户根据可用的在线课程推荐学习路径:

在我当前的模型中,序列是不同的节点。它们标志着用户创建的学习路径的开始,并包含有关序列的其他有用元数据(例如:知识领域、用户评分等)

然后我们使用 NEXT 关系浏览用户定义序列可能包含的所有课程。

单个课程可能是许多不同用户创建的序列的一部分,因此两个课程节点之间可能存在任意数量的 NEXT 关系,并且每个关系都将以父序列的 id 作为属性。

这意味着在获取序列时,dbms 将需要遵循匹配特定 path_id 的 NEXT 关系,以便检索与该课程关联的所有课程节点。

我从不同的来源了解到,使用关系属性来导航图表是一种反模式,因为它会导致 I/O 访问超过关系的数量。

我只希望序列最长约为 20-30 门课程。另一方面,我预计获取整个序列将是应用程序中非常频繁的操作。

我的问题是:这里的反模式是否合理,还是有更好的方法来做到这一点?

【问题讨论】:

    标签: neo4j


    【解决方案1】:

    您可以添加引用Course 节点的新节点(标记为CourseRef),其中CourseRef 节点通过NEXT 关系链接在一起(不存储序列ID)。每个Sequence 节点都会引用链中的第一个CourseRefCourse 节点本身将不再需要链接在一起。

    这可能是新的数据模型:

    (:User)-[:SUBSCRIBED_TO]->(:Sequence)
    (:Sequence)-[:STARTS_AT]->(:CourseRef)
    (:Course)<-[:REFERS_TO]-(:CourseRef)-[:NEXT]->(:CourseRef)
    (:Course)-[:REQUIRED_BY]->(:Course)
    

    使用上述数据模型,您可以通过这种方式为User 的每个Sequence 获取所有Course 路径(可以有多个,如您的示例):

    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

    【讨论】:

    • 这实际上可能是一个非常好的解决方案。我的模型还需要一些数据,以便序列创建者可以添加他们自己关于给定课程的输入(例如,cmets、难度等级等)。这会用一块石头杀死两只鸟。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2022-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多