Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/neo4j/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Neo4j gremlin克隆节点及其边_Neo4j_Graph Databases_Gremlin_Amazon Neptune - Fatal编程技术网

Neo4j gremlin克隆节点及其边

Neo4j gremlin克隆节点及其边,neo4j,graph-databases,gremlin,amazon-neptune,Neo4j,Graph Databases,Gremlin,Amazon Neptune,例如,gremlin是否提供克隆顶点的功能 v1->v2,v1->v3,v1->v4我如何简单有效地创建一个新的顶点v5,它也有指向v2,v3,v4的边,这些边指向的位置与v1的边指向的位置相同,而不必显式地设置它们,而是说g.createvvv1.clonev2之类的话 请注意,我使用的是AWS Neptune版本的gremlin,解决方案必须与之兼容。克隆步骤尚不存在,但可以通过单个查询解决 让我们从一些示例数据开始: gremlin> g = TinkerFactory.create

例如,gremlin是否提供克隆顶点的功能 v1->v2,v1->v3,v1->v4我如何简单有效地创建一个新的顶点v5,它也有指向v2,v3,v4的边,这些边指向的位置与v1的边指向的位置相同,而不必显式地设置它们,而是说g.createvvv1.clonev2之类的话

请注意,我使用的是AWS Neptune版本的gremlin,解决方案必须与之兼容。

克隆步骤尚不存在,但可以通过单个查询解决

让我们从一些示例数据开始:

gremlin> g = TinkerFactory.createModern().traversal()
==>graphtraversalsource[tinkergraph[vertices:6 edges:6], standard]
gremlin> g.V(4).valueMap(true)                                   // the vertex to be cloned
==>[label:person,name:[josh],age:[32],id:4]
gremlin> g.V(4).outE().map(union(identity(), valueMap()).fold()) // all out-edges
==>[e[10][4-created->5],[weight:1.0]]
==>[e[11][4-created->3],[weight:0.4]]
gremlin> g.V(4).inE().map(union(identity(), valueMap()).fold())  // all in-edges
==>[e[8][1-knows->4],[weight:1.0]]
现在,克隆顶点的查询乍一看可能有点吓人,但实际上只是一次又一次地重复相同的模式-在原始和克隆之间跳跃以复制属性:

g.V(4).as('source').
  addV().
    property(label, select('source').label()).as('clone').
  sideEffect(                                                // copy vertex properties
    select('source').properties().as('p').
    select('clone').
      property(select('p').key(), select('p').value())).
  sideEffect(                                                // copy out-edges
    select('source').outE().as('e').
    select('clone').
    addE(select('e').label()).as('eclone').
      to(select('e').inV()).
    select('e').properties().as('p').                        // copy out-edge properties
    select('eclone').
      property(select('p').key(), select('p').value())).
  sideEffect(                                                // copy in-edges
    select('source').inE().as('e').
    select('clone').
    addE(select('e').label()).as('eclone').
      from(select('e').outV()).
    select('e').properties().as('p').                        // copy in-edge properties
    select('eclone').
      property(select('p').key(), select('p').value()))
在实际操作中,它看起来是这样的:

gremlin> g.V(4).as('source').
......1>   addV().
......2>     property(label, select('source').label()).as('clone').
......3>   sideEffect(
......4>     select('source').properties().as('p').
......5>     select('clone').
......6>       property(select('p').key(), select('p').value())).
......7>   sideEffect(
......8>     select('source').outE().as('e').
......9>     select('clone').
.....10>     addE(select('e').label()).as('eclone').
.....11>       to(select('e').inV()).
.....12>     select('e').properties().as('p').
.....13>     select('eclone').
.....14>       property(select('p').key(), select('p').value())).
.....15>   sideEffect(
.....16>     select('source').inE().as('e').
.....17>     select('clone').
.....18>     addE(select('e').label()).as('eclone').
.....19>       from(select('e').outV()).
.....20>     select('e').properties().as('p').
.....21>     select('eclone').
.....22>       property(select('p').key(), select('p').value()))
==>v[13]
gremlin> g.V(13).valueMap(true)                                   // the cloned vertex
==>[label:person,name:[josh],age:[32],id:13]
gremlin> g.V(13).outE().map(union(identity(), valueMap()).fold()) // all cloned out-edges
==>[e[16][13-created->5],[weight:1.0]]
==>[e[17][13-created->3],[weight:0.4]]
gremlin> g.V(13).inE().map(union(identity(), valueMap()).fold())  // all cloned in-edges
==>[e[18][1-knows->13],[weight:1.0]]
更新

分页支持有点棘手。让我把整个过程分成三个步骤。我将使用边ID作为排序标准,并标识最后处理的边,这在Neptune中可能不起作用,但您可以使用唯一的可排序属性

// clone the vertex with its properties
clone = g.V(4).as('source').
  addV().
    property(label, select('source').label()).as('clone').
  sideEffect(
    select('source').properties().as('p').
    select('clone').
      property(select('p').key(), select('p').value())).next()

// clone out-edges
pageSize = 1
lastId = -1
while (true) {
  t = g.V(4).as('source').
    outE().hasId(gt(lastId)).
    order().by(id).limit(pageSize).as('e').
    group('x').
      by(constant('lastId')).
      by(id()).
    V(clone).
    addE(select('e').label()).as('eclone').
      to(select('e').inV()).
    sideEffect(
      select('e').properties().as('p').
      select('eclone').
        property(select('p').key(), select('p').value())).
    count()
  if (t.next() != pageSize)
    break
  lastId = t.getSideEffects().get('x').get('lastId')
}

// clone in-edges
lastId = -1
while (true) {
  t = g.V(4).as('source').
    inE().hasId(gt(lastId)).
    order().by(id).limit(pageSize).as('e').
    group('x').
      by(constant('lastId')).
      by(id()).
    V(clone).
    addE(select('e').label()).as('eclone').
      from(select('e').inV()).
    sideEffect(
      select('e').properties().as('p').
      select('eclone').
        property(select('p').key(), select('p').value())).
    count()
  if (t.next() != pageSize)
    break
  lastId = t.getSideEffects().get('x').get('lastId')
}
我不知道Neptune是否允许您执行完整脚本-如果不允许,您将需要在应用程序代码中执行外部while循环。

克隆步骤还不存在,但可以通过单个查询解决

让我们从一些示例数据开始:

gremlin> g = TinkerFactory.createModern().traversal()
==>graphtraversalsource[tinkergraph[vertices:6 edges:6], standard]
gremlin> g.V(4).valueMap(true)                                   // the vertex to be cloned
==>[label:person,name:[josh],age:[32],id:4]
gremlin> g.V(4).outE().map(union(identity(), valueMap()).fold()) // all out-edges
==>[e[10][4-created->5],[weight:1.0]]
==>[e[11][4-created->3],[weight:0.4]]
gremlin> g.V(4).inE().map(union(identity(), valueMap()).fold())  // all in-edges
==>[e[8][1-knows->4],[weight:1.0]]
现在,克隆顶点的查询乍一看可能有点吓人,但实际上只是一次又一次地重复相同的模式-在原始和克隆之间跳跃以复制属性:

g.V(4).as('source').
  addV().
    property(label, select('source').label()).as('clone').
  sideEffect(                                                // copy vertex properties
    select('source').properties().as('p').
    select('clone').
      property(select('p').key(), select('p').value())).
  sideEffect(                                                // copy out-edges
    select('source').outE().as('e').
    select('clone').
    addE(select('e').label()).as('eclone').
      to(select('e').inV()).
    select('e').properties().as('p').                        // copy out-edge properties
    select('eclone').
      property(select('p').key(), select('p').value())).
  sideEffect(                                                // copy in-edges
    select('source').inE().as('e').
    select('clone').
    addE(select('e').label()).as('eclone').
      from(select('e').outV()).
    select('e').properties().as('p').                        // copy in-edge properties
    select('eclone').
      property(select('p').key(), select('p').value()))
在实际操作中,它看起来是这样的:

gremlin> g.V(4).as('source').
......1>   addV().
......2>     property(label, select('source').label()).as('clone').
......3>   sideEffect(
......4>     select('source').properties().as('p').
......5>     select('clone').
......6>       property(select('p').key(), select('p').value())).
......7>   sideEffect(
......8>     select('source').outE().as('e').
......9>     select('clone').
.....10>     addE(select('e').label()).as('eclone').
.....11>       to(select('e').inV()).
.....12>     select('e').properties().as('p').
.....13>     select('eclone').
.....14>       property(select('p').key(), select('p').value())).
.....15>   sideEffect(
.....16>     select('source').inE().as('e').
.....17>     select('clone').
.....18>     addE(select('e').label()).as('eclone').
.....19>       from(select('e').outV()).
.....20>     select('e').properties().as('p').
.....21>     select('eclone').
.....22>       property(select('p').key(), select('p').value()))
==>v[13]
gremlin> g.V(13).valueMap(true)                                   // the cloned vertex
==>[label:person,name:[josh],age:[32],id:13]
gremlin> g.V(13).outE().map(union(identity(), valueMap()).fold()) // all cloned out-edges
==>[e[16][13-created->5],[weight:1.0]]
==>[e[17][13-created->3],[weight:0.4]]
gremlin> g.V(13).inE().map(union(identity(), valueMap()).fold())  // all cloned in-edges
==>[e[18][1-knows->13],[weight:1.0]]
更新

分页支持有点棘手。让我把整个过程分成三个步骤。我将使用边ID作为排序标准,并标识最后处理的边,这在Neptune中可能不起作用,但您可以使用唯一的可排序属性

// clone the vertex with its properties
clone = g.V(4).as('source').
  addV().
    property(label, select('source').label()).as('clone').
  sideEffect(
    select('source').properties().as('p').
    select('clone').
      property(select('p').key(), select('p').value())).next()

// clone out-edges
pageSize = 1
lastId = -1
while (true) {
  t = g.V(4).as('source').
    outE().hasId(gt(lastId)).
    order().by(id).limit(pageSize).as('e').
    group('x').
      by(constant('lastId')).
      by(id()).
    V(clone).
    addE(select('e').label()).as('eclone').
      to(select('e').inV()).
    sideEffect(
      select('e').properties().as('p').
      select('eclone').
        property(select('p').key(), select('p').value())).
    count()
  if (t.next() != pageSize)
    break
  lastId = t.getSideEffects().get('x').get('lastId')
}

// clone in-edges
lastId = -1
while (true) {
  t = g.V(4).as('source').
    inE().hasId(gt(lastId)).
    order().by(id).limit(pageSize).as('e').
    group('x').
      by(constant('lastId')).
      by(id()).
    V(clone).
    addE(select('e').label()).as('eclone').
      from(select('e').inV()).
    sideEffect(
      select('e').properties().as('p').
      select('eclone').
        property(select('p').key(), select('p').value())).
    count()
  if (t.next() != pageSize)
    break
  lastId = t.getSideEffects().get('x').get('lastId')
}

我不知道Neptune是否允许您执行完整的脚本-如果不允许,您将需要执行应用程序代码中的外部while循环。

您认为这种扩展有多好,以及/或者这种查询有什么限制?如果有1000000个传出/传入边缘,这仍然有效吗?这是否适用于AWS Neptune API?我认为这最终取决于您使用的graph db。然而,拥有这么多的关联边通常被视为一个糟糕的图模型。似乎AWS Neptune将此查询限制为仅999条边,是否有方法对此查询进行分页,以便我可以为具有更多边的节点运行此查询?您将需要有保证的排序顺序和边上的唯一属性,然后它可能会工作。今晚晚些时候,我将尝试将一些内容放在一起,也许只是使用1的页面大小扩展上一个示例。事件边缘同时指传入和传出边缘。对于分页,需要在边上(而不是顶点上)具有唯一的可排序标识符/属性。我将在几分钟后发布一个更新。您认为这个查询的扩展性和/或限制有多大?如果有1000000个传出/传入边缘,这仍然有效吗?这是否适用于AWS Neptune API?我认为这最终取决于您使用的graph db。然而,拥有这么多的关联边通常被视为一个糟糕的图模型。似乎AWS Neptune将此查询限制为仅999条边,是否有方法对此查询进行分页,以便我可以为具有更多边的节点运行此查询?您将需要有保证的排序顺序和边上的唯一属性,然后它可能会工作。今晚晚些时候,我将尝试将一些内容放在一起,也许只是使用1的页面大小扩展上一个示例。事件边缘同时指传入和传出边缘。对于分页,需要在边上(而不是顶点上)具有唯一的可排序标识符/属性。我会在几分钟后发布更新。