Search code examples
arangodbaql

In ArangoDB AQL how do I update fields of every traversed object, regardless of collection?


The UPDATE statement requires a collection name. In a graph, I want to traverse an edge and update each vertex visited.

Something like: FOR v IN 1..50 INBOUND 'pmconfig/6376876' pm_content OPTIONS {uniqueVertices: "global"} [update v.contentsChanged=true]

Since the vertices may be found in different collections, do I have to partition the objects into per-collection lists?


Solution

  • Updating documents using a dynamic (run-time) collection name is not possible. For example, the following AQL query will not compile:

    FOR v IN 1..50 INBOUND 'pmconfig/6376876' pm_content
      UPDATE v WITH { contentsChanged : true } IN PARSE_IDENTIFIER(v._id).collection
    

    The reason is that UPDATE and other data modification statements require their collection names to be known at query compile time. Using bind parameters will work, of course, but no runtime expressions are allowed.

    One workaround is to run the traversal multiple times, each time with a hard-coded collection to update. This still requires knowledge of the collection names in advance. There may also be consistency issues if the graph changes in between:

    FOR v IN 1..50 INBOUND 'pmconfig/6376876' pm_content
      FILTER PARSE_IDENTIFIER(v._id).collection == 'vertexCollection1'
      UPDATE v WITH { contentsChanged : true } IN vertexCollection1
    
    FOR v IN 1..50 INBOUND 'pmconfig/6376876' pm_content
      FILTER PARSE_IDENTIFIER(v._id).collection == 'vertexCollection2'
      UPDATE v WITH { contentsChanged : true } IN vertexCollection2
    
    ...
    

    Another workaround is to have the traversal already generate the per-collection lists, and issue follow-up queries for each collection. For example, the following query should return the keys to update per collection:

    FOR v IN 1..50 INBOUND 'pmconfig/6376876' pm_content
      LET parts = PARSE_IDENTIFIER(v._id) 
      COLLECT collection = parts.collection INTO keys = parts. key 
      RETURN { collection, keys }
    

    Example result:

    [    
      { 
         "collection" : "vertexCollection1", 
         "keys" : [ 
           "abc" 
         ]    
      },    
      { 
        "collection" : "vertexCollection2", 
        "keys" : [ 
          "xyz", 
          "ddd" 
        ]    
      }  
    ]
    

    Using the result structure, the follow-up update queries can be constructed easily and the updates be sent.