【问题标题】:How to perform pagination in Gremlin如何在 Gremlin 中执行分页
【发布时间】:2017-02-11 03:00:21
【问题描述】:

在 Tinkerpop 3 中,如何进行分页?我想获取查询的前 10 个元素,然后是接下来的 10 个,而不必将它们全部加载到内存中。例如,下面的查询返回 1000,000 条记录。我想按 10 x 10 获取它们,而不是一次加载所有 1000,000。

g.V().has("key", value).limit(10)

编辑

在 Gremlin 服务器上通过 HttpChannelizer 工作的解决方案将是理想的。

【问题讨论】:

    标签: gremlin tinkerpop3


    【解决方案1】:

    从功能的角度来看,用于分页的 Gremlin 看起来不错:

    gremlin> g.V().hasLabel('person').fold().as('persons','count').
                   select('persons','count').
                     by(range(local, 0, 2)).
                     by(count(local))
    ==>[persons:[v[1],v[2]],count:4]
    gremlin> g.V().hasLabel('person').fold().as('persons','count').
                   select('persons','count').
                     by(range(local, 2, 4)).
                     by(count(local))
    ==>[persons:[v[4],v[6]],count:4]
    

    通过这种方式,您可以获得带有结果的顶点总数。不幸的是,fold() 迫使您计算所有需要迭代它们的顶点(即将它们全部放入内存)。

    在这种情况下,只要您打算在多个单独的尝试中执行遍历,就真的没有办法避免迭代所有 100,000 个顶点。例如:

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

    第一条语句与使用limit(2) 终止遍历相同。在第二次遍历中,它只需要后两个顶点,它不像你神奇地跳过前两个迭代,因为它是一个新的遍历。我不知道有任何 TinkerPop 图形数据库实现可以有效地做到这一点——它们都有这种行为。

    一次处理十个顶点而不将它们全部保存在内存中的唯一方法是使用与以下相同的Traversal 实例:

    gremlin> t = g.V().hasLabel('person');[]
    gremlin> t.next(2)
    ==>v[1]
    ==>v[2]
    gremlin> t.next(2)
    ==>v[4]
    ==>v[6]
    

    使用该模型,您只需迭代一次顶点,而不会在单个时间点将它们全部放入内存。

    可以在blog post 中找到有关此主题的其他一些想法。

    【讨论】:

    • 谢谢斯蒂芬,最后一个解决方案听起来不错。但是,如果您使用的是HttpChannelizer,您会怎么做?
    • 如果你在做 HTTP,你不能。您必须切换到 websockets,然后才能免费获得该流式传输,或者如果您想更手动地控制它,您可以使用会话。
    • 在python中是否可以通过.next()步骤保存后续多次迭代的遍历?在java中(正如我对janus-graph的理解),它可以通过使用会话进行查询来完成 - 创建会话Client client = cluster.connect("uniqueSessionName",true);,通过一个查询定义遍历变量(例如t = g.V().hasLabel('person');)并在其他查询中迭代该遍历(例如t.next(2))但是pythongremlin怎么做呢?
    • python 中没有connect() 选项,但您可以自己构建“会话”请求消息并通过Client.submit() 发送。该消息的格式为here,与submit() 中显示的here 中构造的标准无会话形式的消息没有太大区别@
    • 谢谢,斯蒂芬。但是,当我尝试在 `message = request.RequestMessage(processor='session', op='eval' ... 'session': '4ad866cd-def9-4a76-86a1-f788785bb482 ', 'aliases': {'g': self._traversal_source}})` ...我收到错误Exception("Unknown processor") - 据我所知serializer.py中没有这样的处理器
    【解决方案2】:

    为什么不在您的 gremlin 查询中添加 order().by() 并执行 range() 函数。

    【讨论】:

      猜你喜欢
      • 2021-12-17
      • 2019-03-15
      • 2016-05-21
      • 1970-01-01
      • 1970-01-01
      • 2020-08-11
      • 2018-04-22
      相关资源
      最近更新 更多