简体   繁体   中英

ArangoDB copy Vertex and Edges to neighbors

I'm trying to copy a vertex node and retain it's relationships in ArangoDB. I'm getting a "access after data-modification" error (1579). It doesn't like it when I iterate over the source node's edges and insert an edge copy within the loop. This makes sense but I'm struggling to figure out how to do what I'm wanting within a single transaction.

var query = arangojs.aqlQuery`
        let tmpNode = (FOR v IN vertices FILTER v._id == ${nodeId} RETURN v)[0]
        let nodeCopy = UNSET(tmpNode, '_id', '_key', '_rev')
        let nodeCopyId = (INSERT nodeCopy IN 'vertices' RETURN NEW._id)[0]
        FOR e IN GRAPH_EDGES('g', ${nodeId}, {'includeData': true, 'maxDepth': 1})
            let tmpEdge = UNSET(e, '_id', '_key', '_rev')
            let edgeCopy = MERGE(tmpEdge, {'_from': nodeCopyId})
            INSERT edgeCopy IN 'edges'
`;

This quesion is somewhat similar to 'In AQL how to re-parent a vertex' - so let me explain this in a similar way.

One should use the ArangoDB 2.8 pattern matching traversals to solve this.

We will copy Alice to become Sally with similar relations:

let alice=DOCUMENT("persons/alice")
let newSally=UNSET(MERGE(alice, {_key: "sally", name: "Sally"}), '_id')
let r=(for v,e in 1..1 ANY alice GRAPH "knows_graph"
          LET me = UNSET(e, "_id",  "_key", "_rev")
          LET newEdge = (me._to == "persons/alice") ?
              MERGE(me, {_to:   "persons/sally"}) :
              MERGE(me, {_from: "persons/sally"})
          INSERT newEdge IN knows RETURN newEdge)
INSERT newSally IN persons RETURN newSally

We therefore first load Alice . We UNSET the properties ArangoDB should set on its own. We change the properties that have to be uniq to be uniq for Alice so we have a Sally afterwards.

Then we open a subquery to traverse ANY first level relations of Alice. In this subequery we want to copy the edges - e . We need to UNSET once more the document attributes that have to be autogenerated by ArangoDB. We need to find out which side of _from and _to pointed to Alice and relocate it to Sally .

The final insert of Sally has to be outside of the subquery, else this statement will attempt to insert one Sally per edge we traverse. We can't insert Saly in front of the query as you already found out - no subsequent fetches are allowed after the insert.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM