Home > Mobile >  How to pass a Collection as a parameter to a user defined function in ArangoDB
How to pass a Collection as a parameter to a user defined function in ArangoDB

Time:10-14

I want to calculate the indegree and outdegree of a node in a graph given the vertex and the edge collection. Below is the code that I have written. UDF function code:

require("@arangodb/aql/functions").register(
    "MYFUNCTIONS::VERTEX::INDEGREE", 
    function(vertex,edge, node) {
        "use strict";
        let db = require('@arangodb').db;
        let aql = require('@arangodb').aql;
        
        let query = aql` for t in ${edge} filter t._to == ${node} COLLECT WITH COUNT INTO length return length`;
        return db._query(query).toArray();
    }
);

When I call the function like below I am getting an error as "AQL: collection or array expected as operand to FOR loop; you specified type 'string' with content '"Transaction"' (while optimizing ast)"

UDF Function calling code: db._query('return MYFUNCTIONS::VERTEX::INDEGREE("Account", "Transaction", "Account/123")');

where Account is a Document Collection, Transaction is an Edge Collection and Account/123 is a node in the graph.

CodePudding user response:

You have to pass a collection, not the name of the collection, for this to work (refer to the documentation here: https://www.arangodb.com/docs/stable/foxx-guides-queries.html#using-collections)

You get the collection with db._collection(name), your user function amended:

require("@arangodb/aql/functions").register(
    "MYFUNCTIONS::VERTEX::INDEGREE", 
    function(vertex,edge, node) {
        "use strict";
        let db = require('@arangodb').db;
        let aql = require('@arangodb').aql;

        let edgeColl = db._collection(edge);
     
        let query = aql` for t in ${edgeColl} filter t._to == ${node} COLLECT WITH COUNT INTO length return length`;
        return db._query(query).toArray();
    }
);

A small working test example (testcoll containts one document, testdoc):

require("@arangodb/aql/functions").register(
  "MYFUNC::TEST", 
  function (coll, key) {
   let db = require('@arangodb').db;
   let aql = require('@arangodb').aql;
   let collo = db._collection(coll);
   let query = aql` FOR t IN ${collo} FILTER t._key == ${key} RETURN t`; 
   return db._query(query).toArray(); 
});

And the call:

@_system> db._query(aql`RETURN MYFUNC::TEST("testcoll", "testdoc")`);
[object ArangoQueryCursor, count: 1, cached: false, hasMore: false]

[
  [
    {
      "_key" : "testdoc",
      "_id" : "testcoll/testdoc",
      "_rev" : "_e7-qE-m---",
      "name" : "test_doc"
    }
  ]
]

  • Related