在进行广度优先搜索时如何在Gremlin中包含边?

时间:2014-04-12 04:53:40

标签: groovy gremlin bulbs rexster

在我的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的树形管道功能非常适合做我想要的!问题是,现在我使用树,我需要将它返回到可以使用的形式...我只能返回顶点或边缘,所以我不能立即返回树。

编辑2:

espeed是对的;我应该使用两个E开头。但是我有一些我想要满足的条件......我几乎已经提前了,但我无法让过滤器正常工作。

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)。我想解决的基本问题是:进行广度优先搜索,仅存储满足所有或更高级别的节点,并将边缘存储在通过测试的所有顶点之间。

2 个答案:

答案 0 :(得分:2)

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

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步骤中过滤顶点时,基本上存储顶点。

答案 1 :(得分:1)

使用bothE()代替both()访问边缘...

请参阅http://gremlindocs.com/#transform/bothe