4

Say I have a collection Col1 that already exists in my database. So, doing something like:

var col = db.collection('Col1');
col.save({"name":"something"});

will work perfectly fine.

But if a collection Col2 that doesn't already exist in my database is tried with the same thing i.e

var col = db.collection('Col2');
col.save({"name":"something"})

will work perfectly fine as well. Only that it doesn't exist and will be not shown in my database. Had it thrown some error or stuffs I could have used try and catch statements for result. But since that is off the plate, how do I know if a collection already exists ?

stj
  • 8,677
  • 15
  • 32
Prasanna
  • 3,027
  • 11
  • 25

4 Answers4

3

There are two things going on here that may be confusing.

First of all, arangojs (unlike the internal JS API of ArangoDB) is asynchronous for everything that needs to talk to the actual ArangoDB server. Asynchronous functions are marked as "async" in the documentation.

You can pass a node.js-style callback (like the async functions in built-in node.js modules, e.g. fs, http, etc) to these methods. Alternatively you can simply omit the callback and the method will return a promise for the result. You can learn more about how promises work in Mozilla's JavaScript reference documentation (this is not specific to Mozilla -- their reference is just very good and generally correct).

The other thing you're running into is the distinction between collection objects in arangojs and actual collections in ArangoDB. The driver lets you create collection objects for collections regardless of whether they exist yet or not. When trying to use them if the collection doesn't actually exist, you will of course see an error.

var col = db.collection('whatever');
col.create() // create the collection if it doesn't exist
.catch(function () {}) // ignore any errors
.then(function () {
  return col.get(); // make sure the collection exists now
})
.then(function () {
  return col.save({some: 'data'});
})
.then(function (result) {
  // everything went fine
})
.catch(function (e) {
  console.error('Something went wrong', e.stack);
});

Or using async/await (if you use Babel or read this answer one year from now):

var col = db.collection('whatever');
try {
  await col.create(); // create the collection if it doesn't exist
} catch (e) {} // ignore any errors
try {
  await col.get(); // make sure the collection exists now
  const result = await col.save({some: 'data'});
  // everything went fine
} catch (e) {
  console.error('Something went wrong', e.stack);
}

Or using node.js-style callbacks because you're oldschool or really like pyramids:

var col = db.collection('whatever');
col.create(function () { // create the collection if it doesn't exist
  // ignore any errors
  col.get(function (err) { // make sure the collection exists now
    if (err) {
      console.error('Something went wrong', err.stack);
      return;
    }
    col.save({some: 'data'}, function (err, result) {
      if (err) {
        console.error('Something went wrong', err.stack);
        return;
      }
      // everything went fine
    });
  });
});
Alan Plum
  • 10,627
  • 4
  • 37
  • 53
2

col.save does not execute the save operation immediately but returns a promise. So it will always succeed. The solution is to wait for the promise to be resolved and then react upon whether an error occurred or not:

var col = db.collection('Col2');
col.save({"name":"something"}).then(
  meta => console.log('Document saved:', meta._rev),  
  err => { console.error('Failed to save document:', err.errorNum, err.response.body.errorMessage); }
);
stj
  • 8,677
  • 15
  • 32
1

https://docs.arangodb.com/3.1/Manual/DataModeling/Collections/DatabaseMethods.html#collection states

returns a single collection or null db._collection(collection-name)

so you can use

var col2 = db._collection('Col2');
if (col2) {
    // collection exists
    col2.save({"name":"something"});
}
sevcik.tk
  • 434
  • 5
  • 5
  • Although the documentation for arangoDB says it works, the node's package `arangojs` doesn't agree with it. For collection that doesn't exist my code shows `true` when kept into the if clause. I wanted an arangojs solution. Currently I am just checking for collection name in the list of all collections to check for the collection's existence. But my method is very crude and I do not like it myself – Prasanna Nov 10 '16 at 04:29
0

This is old, but there is an exists() function.

Example in typescript/node

const metaResult = db.collection('myCollection');
if(!await metaResult.exists()) {
    await db.createCollection('myCollection');
}