3

I'm creating some removal queries for vertices and edges in ArangoDB using AQL and I assumed there would be a "safe" way to delete vertices that would also remove associated edges. But I can't find any in the documentation or anywhere else. Is the following the best way to do a safe delete?

FOR e IN GRAPH_EDGES('EdgeClass',docId,{direction:'any',maxDepth:1, includeData:false})
    REMOVE e._key FROM EdgeClass

combined with

REMOVE docKey IN DocumentClass

Also, is there a way to remove vertices (or edges) using _ids or is it necessary to use _keys? I couldn't get the former to work.

ropeladder
  • 1,103
  • 11
  • 24

2 Answers2

3

Deleting vertices is currently not handled via AQL. The graph management interface offers vertex deletion functionality.

The programming language specific driver usually offers wrappers for the REST interfaces to these methods.

If you want to design an AQL query that does this for you, you'd i.e. have to know whether a vertex is only used in one graph, and the number of edge collections that could be concerned by this deletion. You would probably want to use the more modern graph traversals. Lets try to remove eve from the knows graph:

LET keys = (
  FOR v, e IN 1..1 ANY 'persons/eve' GRAPH 'knows_graph' RETURN e._key)
     LET r = (FOR key IN keys REMOVE key IN knows) REMOVE 'eve' IN persons

So, we let the the traversal give us the _key of all edges of Eve. We then remove all these edges from the knows edge collection. After that we remove Eve herself.

However, you can easily see that you have to craft such a query specific for your situation.

edit: one can do this a little more elegant like this:

LET keys = (FOR v, e IN 1..1 ANY 'persons/eve' GRAPH 'knows_graph'
            REMOVE e._key IN knows)
  REMOVE 'eve' IN persons
dothebart
  • 5,972
  • 16
  • 40
  • Thanks. I'm using arangojs in Node, so I tried this function: https://github.com/arangodb/arangojs#graphvertexcollectionremove . However, it still doesn't seem to be deleting neighboring edges. Any idea what I might be doing wrong? Simply calling REST interface using curl does delete both the vertex and neighboring edges. – ropeladder Feb 02 '16 at 21:28
  • 2
    @ropeladder the behaviour of that function changed in the last minor release to match the expected behaviour. It was previously just using the raw collection API which could result in dangling edges, now it uses the graph collection API. Could you make sure you are using the latest version of arangojs? – Alan Plum Feb 03 '16 at 10:30
  • Yep, not using the latest arangojs was the problem. Thanks! – ropeladder Feb 03 '16 at 12:34
  • I see in the ArangoDB documentation: > "Data-modification queries are restricted to modifying data in a single collection per query. That means a data-modification query cannot modify data in multiple collections with a single query." I wondered if the documentation is out of date, if it is indeed possible to remove documents from multiple collections in a single AQL query? – rom99 Mar 14 '17 at 10:21
  • Yes, it has been removed meanwhile. The documentation needs to be fixed. – dothebart Mar 14 '17 at 16:10
  • However, you can't specify multiple delete/update statements for one collection in a query. – dothebart Mar 14 '17 at 16:16
  • Your edit assigns to `keys` but never uses it for anything. – Raman May 16 '19 at 18:25
  • meanwhile the gharial API has been rewritten in C++, so the performance penalty of using it has become smaller. As parts of the AQL described above, all whats said there remains true. – dothebart May 17 '19 at 09:36
0

I banged my head to find out why @dothebart's answer didn't work for me, until I made experiments and found out several things:

  • I had auto generated _key in number format
  • REMOVE 'eve' IN persons required string value
  • bindvar didn't convert @cartKey number to string

So turned out I had to quote the _key in the query and removed the bindvars completely. I am not sure whether it is a bug or by design.

LET edgeKeys = (FOR v, e IN 1..1 ANY 'cart/2648355' GRAPH 'cart_graph' RETURN e._key)
LET r = (
  FOR key IN edgeKeys
    REMOVE key IN store_cart OPTIONS { ignoreErrors: true }
    REMOVE key IN product_cart OPTIONS { ignoreErrors: true }
  )
REMOVE '2648355' IN cart
goldsky
  • 801
  • 7
  • 11