【问题标题】:How to include edges in Gremlin while doing breadth first search?如何在进行广度优先搜索时在 Gremlin 中包含边?
【发布时间】:2014-05-26 09:56:57
【问题描述】:

在我的 gremlin 查询中,我有以下内容:

vert.as('x').
both.or(
  _().has("time").filter{ it.time.toInteger() > startTime.toInteger() },
  _().has("isRead"), _().has("isWrite")).dedup().gather.scatter.
store(y).loop('x'){c++ < limit.toInteger()}.iterate();

在我的 gremlin 脚本中,我返回 y,但 y 显然只有顶点。我可以通过为每个顶点迭代它们来手动检索每个边,但是我想要一个返回的列表,其中只包含在列表 y 中返回的其他节点之间的边。

特别是,我需要能够在本地重新创建在数据结构中返回的子图,因此使用 gremlin 来返回该信息。关于我的用例影响这些需求的其他细节是,手动迭代每个节点边缘太慢,因为我正在运行我的灯泡脚本的 rexster 服务器必须通过网络推送数据,而且还因为如果我没有使用脚本最初返回的每个顶点之间的边集,那么我必须检查沿每条边遇到的每个顶点,以确保它在最初返回的集合内;非常不理想。

基本上,任何结果都应该是这样的,当我查看任何返回的顶点时,我可以知道返回集合中链接了哪些顶点——而无需进行任何手动检查或查找。它应该只是在数据集中。

编辑 1:

我发现 gremlin 的树管道功能非常适合做我想做的事!问题是,既然我使用了tree,我需要将它返回到可以使用的形式......我只能返回顶点或边,所以我不能马上返回树。

编辑 2:

espeed 是对的;我应该使用bothE 开始。但是我有一些条件我想满足……我之前差点就有了,但是我无法让过滤器正常工作。

vert.as('l').
bothE.gather.scatter.as('edge').bothV.or(
  _().has("time").filter{ it.getProperty('time').toInteger() >= startTime.toInteger() },
  _().has("isRead"), _().has("isWrite")).
dedup().store(results).as('vertice').back('edge').store(results).back('vertice')
.loop('l'){c++ < limit.toInteger()}.iterate();

我不明白为什么我不能在一个管道中使用两个后端(我得到一个 NullPointerException 与这个管道)。我要解决的基本问题是:进行广度优先搜索,只存储满足以上所有条件的节点,并存储所有通过测试的顶点之间的边。

【问题讨论】:

    标签: groovy gremlin bulbs rexster


    【解决方案1】:

    不要过多地弄乱你的代码,也许最简单的事情就是这样做:

    results = [] as Set
    vert.as('l').
    bothE.as('e').gather.scatter.as('edge').bothV.or(
      _().has("time").filter{ it.getProperty('time').toInteger() >= startTime.toInteger()}.store(results),
      _().has("isRead"), _().has("isWrite")).store(results))
    .sideEffect{e,m->results<<m.e}
    .loop('l'){c++ < limit.toInteger()}.iterate();
    

    请注意,将结果声明为 Set 可以避免 dedup 步骤。基本上在or 步骤中过滤顶点时存储顶点。

    【讨论】:

    • 嗯,这非常接近我想要做的事情,而且我想我在一遍又一遍地编辑代码时做了类似的事情;这样做的问题是,当您执行 back('edge') 时,它会将结果从边缘转发到存储,但存储也只是将其传递。当循环获取当前元素值时,它是一条边,并且在 as('l') 处,它应该是一个顶点,以便让 bothE 解析。这就是为什么我不得不“支持”那里的碎片,但它总是抛出 NullPointerException...
    • 移动 as('l') 并不能解决它;我认为唯一需要发生的是存储在 has("isWrite")).store(results) 的顶点需要是被发送回 as('l') 的顶点...
    • 我摆脱了背部,只是通过命名边缘步骤并从 sideEffect 引用它来“欺骗”...这行得通吗?只是想让你得到一个答案,这样你就可以从那里迭代...也许这不是最好的方法。
    • 这看起来正确,非常感谢,我不知道该怎么做,我什至研究过,但我不熟悉 Groovy。虽然看起来是对的,但是当我运行它时,即使我增加了限制,它似乎并没有增加更多的结果......我会回来看看为什么,它可能是我的数据......
    • 使用 Gremlin REPL 来编辑/调试 Gremlin 脚本(Rexster 不是为了那个)。理想情况下,您应该像测试 Python 脚本一样创建/测试 Gremlin 脚本——为代码创建 Gremlin-Groovy 文件并运行 Groovy 测试——这个流程要容易得多。然后,一旦您的 Gremlin 脚本工作,将其添加到灯泡。
    【解决方案2】:

    使用bothE() 而不是both() 来访问边缘...

    见http://gremlindocs.com/#transform/bothe

    【讨论】:

    • 再次感谢espeed。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-13
    • 1970-01-01
    相关资源
    最近更新 更多