Database Interface

It’s the main class to operate with ArcadeDB. To obtain an instance of Database, use the class DatabaseFactory.

Methods (By category)

Transaction Lifecycle Query Records Misc

transaction() default

close()

query() positional parameters

newDocument()

async()

transaction() with retries

drop()

query() (parameter map)

newVertex()

command() positional parameters

begin()

isOpen()

lookupByKey()

newEdgeByKeys()

command() (parameter map)

commit()

lookupByRID()

deleteRecord()

getSchema()

rollback()

iterateType()

getSize()

iterateBucket()

scanBucket()

scanType()

select()


async()

It returns an instance of DatabaseAsyncExecutor to execute asynchronous calls.

Syntax:

DatabaseAsyncExecutor async()

Example:

Execute an asynchronous query:

db.async().query("sql", "select from User", new AsyncResultsetCallback() {
  @Override
  public boolean onNext(Result result) {
    System.out.println( "Name = " + result.getProperty("name"));
    return true;
  }

  @Override
  public void onError(Exception exception) {
    System.err.println("Error on executing the query: " + exception );
  }
});

begin()

Starts a transaction on the current thread. Each thread can have only one active transaction. All the modification to the database become persistent only at pending changes in the transaction are made persistent only when the commit() method is called. ArcadeDB supports ACID transactions. Before the commit, no other thread/client can see any of the changes contained in the current transaction.

Syntax:

begin()

Example:

db.begin();  // <--- AT THIS POINT THE TRANSACTION IS STARTED AND ALL THE CHANGES ARE COLLECTED TILL THE COMMIT (SEE BELOW)
try{
  // YOUR CODE HERE
  db.commit();
} catch( Exception e ){
  db.rollback();
}

close()

Closes a database. This method should be called at the end of the application. By using Java7+ AutoClosed statement, the close() method is executed automatically at the end of the scope of the database variable.

Syntax:

void close()

Example:

Database db = new DatabaseFactory("/temp/mydb").open();
try{
  // YOUR CODE HERE
} finally {
  db.close();
}

The suggested method is using Java7+ AutoClosed statement, to avoid the explicit close() calling:

try( Database db = new DatabaseFactory("/temp/mydb").open(); ) {
  // YOUR CODE
}

drop()

Drops a database. The database will be completely removed from the filesystem.

Syntax:

void drop()

Example:

new DatabaseFactory("/temp/mydb").open().drop();

getSchema()

Returns the Schema instance for the database.

Syntax:

Schema getSchema()

Example:

db.getSchema().createVertexType("Song");

getSize()

Returns the size of the database in bytes.

Syntax:

Schema getSize()

Example:

db.getSize();

isOpen()

Returns true if the database is open, otherwise false.

Syntax:

boolean isOpen()

Example:

if( db.isOpen() ){
  // YOUR CODE HERE
}

query( language, command, positionalParameters )

Executes a query, with optional positional parameters. This method only executes idempotent statements, namely SELECT and MATCH, that cannot change the database. The execution of any other commands will throw a IllegalArgumentException exception.

Syntax:

Resultset query( String language, String command, Object... positionalParameters )

Where:

  • language is the language to use. Only "SQL" language is supported for now, but in the future multiple languages could be used

  • command is the command to execute. If the language supports prepared statements (SQL does), you can specify parameters by using ? for positional replacement

  • positionalParameters optional variable array of parameters to execute with the query

It returns a Resultset object where the result can be iterated.

Examples:

Simple query:

ResultSet resultset = db.query("sql", "select from V");
while (resultset.hasNext()) {
  Result record = resultset.next();
  System.out.println( "Found record, name = " + record.getProperty("name"));
}

Query passing positional parameters:

ResultSet resultset = db.query("sql", "select from V where age > ? and city = ?", 18, "Melbourne");
while (resultset.hasNext()) {
  Result record = resultset.next();
  System.out.println( "Found record, name = " + record.getProperty("name"));
}

query( language, command, parameterMap )

Executes a query taking a map for parameters. This method only executes idempotent statements, namely SELECT and MATCH, that cannot change the database. The execution of any other commands will throw a IllegalArgumentException exception.

Syntax:

Resultset query( String language, String command, Map<String,Object> parameterMap )

Where:

  • language is the language to use. Only "SQL" language is supported for now, but in the future multiple languages could be used

  • command is the command to execute. If the language supports prepared statements (SQL does), you can specify parameters by name by using :<arg-name>

  • parameterMap this map is used to extract the named parameters

It returns a Resultset object where the result can be iterated.

Examples:

Map<String,Object> parameters = new HashMap<>();
parameters.put("age", 18);
parameters.put("city", "Melbourne");

ResultSet resultset = db.query("sql", "select from V where age > :age and city = :city", parameters);
while (resultset.hasNext()) {
  Result record = resultset.next();
  System.out.println( "Found record, name = " + record.getProperty("name"));
}

command( language, command, positionalParameters )

Executes a command that could change the database. This is the equivalent to query(), but allows the command to modify the database. Only "SQL" language is supported, but in the future multiple languages could be used.

Syntax:

Resultset command( String language, String command, Object... positionalParameters )

Where:

  • language is the language to use. Only "SQL" is supported

  • command is the command to execute. If the language supports prepared statements (SQL does), you can specify parameters by using ? for positional replacement or by name by using :<arg-name>

  • positionalParameters optional variable array of parameters to execute with the query

It returns a Resultset object where the result can be iterated.

Examples:

Create a new record:

db.command("sql", "insert into V set name = 'Jay', surname = 'Miner'");

Create a new record by passing position parameters:

db.command("sql", "insert into V set name = ?, surname = ?", "Jay", "Miner");

command( language, command, parameterMap )

Executes a command that could change the database. This is the equivalent to query(), but allows the command to modify the database. Only "SQL" language is supported, but in the future multiple languages could be used.

Syntax:

Resultset command( String language, String command, Map<String,Object> parameterMap )

Where:

  • language is the language to use. Only "SQL" is supported

  • command is the command to execute. If the language supports prepared statements (SQL does), you can specify parameters by using ? for positional replacement or by name by using :<arg-name>

  • parameterMap this map is used to extract the named parameters

It returns a Resultset object where the result can be iterated.

Examples:

Create a new record by passing a map of parameters:

Map<String,Object> parameters = new HashMap<>();
parameters.put("name", "Jay");
parameters.put("surname", "Miner");

db.command("sql", "insert into V set name = :name, surname = :surname", parameters);

commit()

Commits the thread’s active transaction. All the pending changes in the transaction are made persistent. A transaction must be begun by calling the begin() method. Rolled back transactions cannot be committed. ArcadeDB supports ACID transactions. Before the commit, no other thread/client can see any of the changes contained in the current transaction. ArcadeDB uses a WAL (Write Ahead Log) as journal in case a crash happens at commit time. In this way, at the next restart, the database can be rollbacked at the previous state. If the commit operation succeed, the changes are immediately visible to the other threads/clients and further transactions of the current thread.

Syntax:

commit()

Example:

db.begin();
try{
  // YOUR CODE HERE
  db.commit();  // <--- COMMIT ALL THE CHANGES "ALL OR NOTHING" IN PERSISTENT WAY
} catch( Exception e ){
  db.rollback();
}

deleteRecord( record )

Deleted a record. The record will be persistently deleted only at commit time.

Syntax:

void deleteRecord( Record record )

Examples:

db.deleteRecord( customer );

iterateBucket( bucketName )

Iterates all the records contained in a bucket. To scan a type (with all its buckets), use the method iterateType() instead. The result are not accumulated in RAM, but rather this method returns an Iterator<Record> that fetches the records only when .next() is called.

Syntax:

Iterator<Record> iterateBucket( String bucketName )

Example:

Aggregate the records by age. This is equivalent to a SQL query with a "group by age":

Map<String, AtomicInteger> aggregate = new HashMap<>();

Iterator<Record> result = db.iterateType("V", true );
while( result.hasNext() ){
  Record record = result.next();

  String age = (String) record.get("age");
  AtomicInteger counter = aggregate.get(age);
  if (counter == null) {
    counter = new AtomicInteger(1);
    aggregate.put(age, counter);
  } else
    counter.incrementAndGet();
}

Example:

Prints all the records in the bucket "Customer" with age major or equals to 21.

Iterator<Record> result = db.iterateBucket("Customer");
while( result.hasNext() ){
  Record record = result.next();

  Integer age = (Integer) record.get("age");
  if (age =! null && age >= 21 )
    System.out.println("Found customer: " + record.get("name") );
}

iterateType( className, polymorphic )

Iterates all the records contained in the buckets relative to a type. If polymorphic is true, then also the sub-types buckets are considered. To iterate one bucket only check out the iterateBucket() method. The result are not accumulated in RAM, but rather this method returns an Iterator<Record> that fetches the records only when .next() is called.

Syntax:

Iterator<Record> iterateType( String typeName, boolean polymorphic )

Example:

Aggregate the records by age. This is equivalent to a SQL query with a "group by age":

Map<String, AtomicInteger> aggregate = new HashMap<>();

Iterator<Record> result = db.iterateType("V", true );
while( result.hasNext() ){
  Record record = result.next();

  String age = (String) record.get("age");
  AtomicInteger counter = aggregate.get(age);
  if (counter == null) {
    counter = new AtomicInteger(1);
    aggregate.put(age, counter);
  } else
    counter.incrementAndGet();
}

lookupByKey( type, properties, keys )

Look ups for one or more records (document, vertex or edge) that match one or more indexed keys.

Syntax:

Cursor<RID> lookupByKey( String type, String[] properties, Object[] keys )

Where:

  • type type name

  • properties array of property names to match

  • keys array of keys

It returns a Cursor<RID> (like an iterator).

Examples:

Look up for an author with name "Jay" and surname "Miner". This requires an index on the type "Author", properties "name" and "surname".

Cursor<RID> jayMiner = database.lookupByKey("Author", new String[] { "name", "surname" }, new Object[] { "Jay", "Miner" });
while( jayMiner.hasNext() ){
  System.out.println( "Found Jay! " + jayMiner.next().getProperty("name"));
}

lookupByRID( rid, loadContent )

Look ups for a record (document, vertex or edge) by its RID (Record Identifier).

Syntax:

Record lookupByRID( RID rid, boolean loadContent )

Where:

  • rid is the record identifier

  • loadContent forces the load of the content too. If the content is not loaded will be lazy loaded at the first access. Use true if you are going to access to the record content for sure, otherwise, use false

It returns a Record implementation (document, vertex or edge).

Examples:

Load the vertex by RID and its content:

Vertex v = (Vertex) db.lookupByRID(new RID(db, "#3:47"));

newDocument( typeName )

Creates a new document of a certain type. The type must be of type "document" and must be created beforehand. In order to be saved, the method MutableDocument.save() must be called.

Syntax:

MutableDocument newDocument( typeName )

Where:

  • typeName type name

It returns a MutableDocument instance.

Examples:

Create a new document of type "Customer":

MutableDocument doc = db.newDocument("Customer");
doc.set("name", "Jay");
doc.set("surname", "Miner");
doc.save();  // THE DOCUMENT IS SAVED IN THE DATABASE ONLY WHEN `.save()` IS CALLED

newVertex( typeName )

Creates a new vertex of a certain type. The type must be of type "vertex" and must be created beforehand. In order to be saved, the method MutableVertex.save() must be called.

Syntax:

MutableVertex newVertex( typeName )

Where:

  • typeName type name

It returns a MutableVertex instance.

Examples:

Create a new document of type "Customer":

MutableVertex v = db.newVertex("Customer");
v.set("name", "Jay");
v.set("surname", "Miner");
v.save();

newEdgeByKeys( sourceVertexType, sourceVertexKey, sourceVertexValue, destinationVertexType, destinationVertexKey, destinationVertexValue, createVertexIfNotExist, edgeType, bidirectional, properties )

Creates a new edge between two vertices found by their keys.

Syntax:

Edge newEdgeByKeys( String sourceVertexType, String[] sourceVertexKey,
                    Object[] sourceVertexValue,
                    String destinationVertexType, String[] destinationVertexKey,
                    Object[] destinationVertexValue,
                    boolean createVertexIfNotExist, String edgeType, boolean bidirectional,
                    Object... properties )

Where:

  • sourceVertexType source vertex type name

  • sourceVertexKey source vertex key properties

  • sourceVertexValue source vertex key values

  • destinationVertexType destination vertex type name

  • destinationVertexKey destination vertex key properties

  • destinationVertexValue destination vertex key values

  • createVertexIfNotExist creates source and/or destination vertices if not exist

  • edgeType edge type name

  • bidirectional true if the edge must be bidirectional, otherwise false

  • properties optional property array with pairs of name (as string) and value

It returns a MutableEdge instance.

Examples:

Create a new document of type "Customer":

Edge likes = db.newEdgeByKeys( "Account",
                                new String[] {"id"}, new Object[] {322323},
                               "Song",
                                new String[] {"title"},
                                new Object[] {"Chasing Cars"},
                               false, "Likes", true);
likes.save();

rollback()

Aborts the thread’s active transaction by rolling back all the pending changes. Usually the transaction rollback is executed in case of errors. If an exception happens during the call commit(), the transaction is roll backed automatically. Once rolled backed, the transaction cannot be committed anymore but it has to be re-started by calling the begin() method.

Syntax:

rollback()

Example:

db.begin();
try{
  // YOUR CODE HERE
  db.commit();
} catch( Exception e ){
  db.rollback(); // <--- ROLLBACK IN CASE OF EXCEPTION
}

scanBucket( bucketName, callback )

Scans all the records contained in a buckets. For each record found, the callback is called passing the current record. To scan a type (with all its buckets), use the method scanType() instead. The callback method must return true to continue the scan, otherwise false. Look also at the iterateBucket() method if you want to use an iterator approach instead of callback.

Syntax:

void scanBucket(String bucketName, RecordCallback callback);

Example:

Prints all the records in the bucket "Customer" with age major or equals to 21.

db.scanBucket("Customer", (record) -> {
  Integer age = (Integer) record.get("age");
  if (age =! null && age >= 21 )
    System.out.println("Found customer: " + record.get("name") );
  return true;
});

scanType( className, polymorphic, callback )

Scans all the records contained in all the buckets relative to a type. If polymorphic is true, then also the sub-types buckets are considered. For each record found, the callback is called passing the current record. To scan one bucket only check out the scanBucket() method. The callback method must return true to continue the scan, otherwise false. Look also at the iterateType() method if you want to use an iterator approach instead of callback.

Syntax:

scanType( String className, boolean polymorphic, DocumentCallback callback )

Example:

Aggregate the records by age. This is equivalent to a SQL query with a "group by age":

Map<String, AtomicInteger> aggregate = new HashMap<>();

db.scanType("V", true, (record) -> {
  String age = (String) record.get("age");
  AtomicInteger counter = aggregate.get(age);
  if (counter == null) {
    counter = new AtomicInteger(1);
    aggregate.put(age, counter);
  } else
    counter.incrementAndGet();

  return true;
});

select()

Returns a Select builder to construct and execute queries using the Native Select API. This provides a zero-parsing, JIT-friendly fluent query builder as an alternative to SQL or Cypher.

Syntax:

Select select()

It returns a Select instance that supports fluent chaining for building queries.

Examples:

Simple query:

Vertex v = db.select().fromType("Person")
    .where().property("name").eq().value("John")
    .vertices().nextOrNull();

With count:

long count = db.select().fromType("Person")
    .where().property("active").eq().value(true)
    .count();

With stream:

List<String> names = db.select().fromType("Person")
    .where().property("age").gt().value(18)
    .stream()
    .map(d -> d.getString("name"))
    .collect(Collectors.toList());

See the Native Select API documentation for the full reference including operators, graph traversal, and vector search.


transaction( txBlock )

This methods wraps a call to the method transaction with retries by using the default retries specified in the database setting arcadedb.mvccRetries.


transaction( txBlock, retries )

Executes a transaction block as a callback or a clojure. Before calling the callback in TransactionScope, the transaction is begun and after the end of the callback, the transaction is committed. In case of any exceptions, the transaction is rolled back. In case a NeedRetryException exceptions is thrown, the transaction is repeated up to retries times

Syntax:

void transaction( TransactionScope txBlock )

Examples:

Example by using Java21+ syntax:

db.transaction( () -> {
  final MutableVertex v = database.newVertex("Author");
  v.set("name", "Jay");
  v.set("surname", "Miner");
  v.save();
});

Example by using Java7 syntax:

db.transaction( new Database.TransactionScope() {
  @Override
  public void execute(Database database) {
    final MutableVertex v = database.newVertex("Author");
    v.set("name", "Jay");
    v.set("surname", "Miner");
    v.save();
  }
});