【问题标题】:How to delete duplicate edges by inV outV and specific properties?如何通过 inV outV 和特定属性删除重复边?
【发布时间】:2019-03-29 14:29:06
【问题描述】:

我在图中有重复的边,它们具有相同的 inV、outV 和一些(但不是全部)属性。除了其中一个重复项之外,我想删除所有重复项。

给定下图:

g.addV().property(id, '1').
addV().property(id, '2').
addV().property(id, '3').
addV().property(id, '4').
addE('link').property('prop1', 000).property('prop2', 111).from(V('1')).to(V('2')).
addE('link').property('prop1', 000).property('prop2', 112).from(V('1')).to(V('2')).
addE('link').property('prop1', 000).property('prop2', 113).from(V('1')).to(V('2')).
addE('link').property('prop1', 222).property('prop2', 333).from(V('2')).to(V('3')).
addE('link').property('prop1', 222).property('prop2', 334).from(V('2')).to(V('3')).
addE('link').property('prop1', 222).property('prop2', 335).from(V('2')).to(V('3')).
addE('link').property('prop1', 222).property('prop2', 336).from(V('2')).to(V('3')).
addE('link').property('prop1', 333).property('prop2', 444).from(V('2')).to(V('3')).
addE('link').property('prop1', 333).property('prop2', 444).from(V('3')).to(V('4')).
addE('link').property('prop1', 333).property('prop2', 445).from(V('3')).to(V('4')).
addE('link').property('prop1', 333).property('prop2', 446).from(V('3')).to(V('4')).iterate()

我想删除inVoutVprop1 的所有重复项,因此只留下以下边:

addE('link').property('prop1', 000).property('prop2', 111).from(V('1')).to(V('2')).
addE('link').property('prop1', 222).property('prop2', 336).from(V('2')).to(V('3')).
addE('link').property('prop1', 333).property('prop2', 444).from(V('2')).to(V('3')).
addE('link').property('prop1', 333).property('prop2', 446).from(V('3')).to(V('4'))

编辑:为了澄清,我想通过检查 inVoutVprop1 来删除重复的边缘,如果有多个边缘与所有这 3 个参数匹配我想要无论prop2 是否唯一,保留一个并删除其余的。

【问题讨论】:

  • 我无法从您的预期结果中检测到模式,关于移除属性的确切决策标准是什么?
  • 所以我想遍历每个节点,获取它们的所有边,检查是否有多个边 inV、outV 和 prop1 相同,如果它们相同,则保留一个并删除其余部分,无论 prop2 是否唯一。

标签: gremlin


【解决方案1】:
g.E().as('e').outV().id().as('ov').
  select('e').inV().id().as('iv').
  select('e').properties('prop1').value().as('p1').
  select('e', 'ov', 'iv', 'p1').
  group().
    by(select('ov', 'iv', 'p1')).
    by(select('e')).
  select(values).as('unique_e').
  V().outE().where(without('unique_e')).drop()

【讨论】:

  • 哇,非常感谢!选择重复值的方法几乎相同,但我不知道如何在不删除所有边缘的情况下进行删除。太棒了!
  • 这只是从我的图表中删除了所有边.. 不知道为什么,但是
【解决方案2】:

我认为您的删除标准的性质(特别是,您只想立即将遇到的 drop() 重复)允许我们使用 Gremlin 食谱中描述的 Duplicate Edge Detection Pattern 的修改。

gremlin> g.V().as('ov').
......1>   outE().as('e').
......2>   inV().as('iv').
......3>   sideEffect(inE().
......4>              where(neq('e')).
......5>              where(eq('e')).by(label).
......6>              where(outV().as('ov')).
......7>              where(eq('e')).by('prop1').drop()).iterate()
gremlin> g.E()
==>e[0][1-link->2]
==>e[3][2-link->3]
==>e[7][2-link->3]
==>e[8][3-link->4]

一般模式会有所偏差,因为您不关心“检测”重复项(因此不需要分组和计数过滤的费用),您只需关心立即删除任何符合您的条件的重复项。

这里唯一可能比较棘手的是,您使用的特定图表是否特别渴望评估遍历步骤。换句话说,如果您drop() 一条边是否会立即从第 1 行和第 3 行的未来迭代中删除?如果没有,那可能会带来一些麻烦。但是,大多数图表的工作原理如下所示(我在 TinkerGraph 上进行了测试),因此这种方法可能对您有用。

【讨论】:

  • 感谢您的回复,虽然很遗憾我在生产中使用不支持副作用功能的 Amazon Neptune。我确实在 Neptune 的小图中测试了上述答案,它确实有效,我不知道它在更大的图中如何工作。
  • 您可以改用local()map() - 应该类似地工作。我认为与其他答案相比,这种方法的性能会更好,因为您不必构建Map 然后重申V()。但我认为,如果您在全球范围内检测重复项,那么两者都将是昂贵/不可能的遍历。理想情况下,您希望将基于 OLAP 的 Gremlin 与 Spark 结合使用来帮助解决此问题,但我不确定 Neptune 是否支持。另一方面,如果您在本地对一组存在重复问题的已知顶点执行此遍历,那么我怀疑它会更易于管理。
  • 啊有趣,好吧,我会用local()试试。是的,我也担心在实际数据集上运行是不可能的,至少是整个事情,是的,Neptune 不支持 OLAP。我希望我可以限制遍历足够多的步骤。
  • 确实比我的优雅得多
猜你喜欢
  • 2019-01-23
  • 1970-01-01
  • 2017-04-15
  • 1970-01-01
  • 2021-04-04
  • 2015-08-06
  • 2023-03-15
  • 1970-01-01
  • 2012-08-12
相关资源
最近更新 更多