如何使用Gremlin / Tinkerpop

时间:2016-10-24 17:59:38

标签: titan gremlin tinkerpop tinkerpop3 ibm-graph

我在IBM Graph(由Cassandra支持的TitanDB)中建模了一个非常基本的新闻源,如下所示:

enter image description here

我正在尝试编写执行以下操作的查询:

  1. 从顶点USER: John.Smith
  2. 开始
  3. 从用户FRIENDS中获取最近的15篇帖子以及他自己的帖子。
  4. 检查USER: John.Smith是否喜欢这些帖子,并返回每个帖子的简单is_liked布尔属性。
  5. 此查询有几个先决条件:

    • 在每个返回的帖子中,还应返回发布USER的属性。为了这个问题,只需要avatar属性。
    • 我需要能够对这些结果进行分页。一旦我找到了前15个帖子,我就需要能够返回接下来的15个,然后是下一个等等。

    获取用户朋友和他们的LATEST_POSTS

    是没问题的
    g.V().hasLabel("USER").has("userid", "John.Smith").both("FRIEND").out("LATEST_POST");
    

    我已阅读Tinkerpop文档,但我发现自己仍然迷失了如何开始构建此查询以满足我的要求。

    此外,在性能,数据建模,架构或索引建议方面对此方法的任何评论都将非常有用。即我是否希望这种方法能够实时大规模检索Feed?

    提前致谢。

2 个答案:

答案 0 :(得分:4)

对于给定的图模式,查询将是这样的:

g.V().has("user", "userid", "John.Smith").as("john").
  union(identity(), both("FRIEND")).as("user").
  out("LATEST_POST").
  flatMap(emit().repeat(out("PREVIOUS_POST")).range(page * pageSize, (page + 1) * pageSize)).as("post").
  choose(__.in("LIKED").where(eq("john")), constant(true), constant(false)).as("likedByJohn")
  select("user", "post", "likedByJohn")

但是Alaa已经指出这种方法不会扩展,以及如何改进图形模式。

答案 1 :(得分:1)

您应该在http://tinkerpop.apache.org/docs/3.2.3-SNAPSHOT/recipes/#pagination中查看分页配方。这是一次检索一个范围/页面的简化方法

gremlin> g.V().hasLabel('person').range(0,2)
==>v[1]
==>v[2]
gremlin> g.V().hasLabel('person').range(2,4)
==>v[4]
==>v[6]

关于你拥有的模型,我会避免使用LATEST_POST边缘,因为每次用户有新帖子时你都需要不断更新这个边缘。最好在帖子中添加时间戳属性,并且您始终可以在时间戳上对返回的结果进行排序以获取最新的帖子。