ArangoDB v2.8 reached End of Life (EOL) and is no longer supported.

This documentation is outdated. Please see the most recent version here: Try latest

Details on FoxxRepository

A repository is a gateway to the database. It gets data from the database, updates it or saves new data. It uses the given model when it returns a model and expects instances of the model for methods like save. In your repository file, export the repository as repository.

var Foxx = require("org/arangodb/foxx");

var TodosRepository = Foxx.Repository.extend({
    // ...
});

exports.repository = TodosRepository;

The following events are emitted by a repository:

  • beforeCreate
  • afterCreate
  • beforeSave
  • afterSave
  • beforeUpdate
  • afterUpdate
  • beforeRemove
  • afterRemove

Model lifecycle:

var person = new PersonModel();
person.on('beforeCreate', function() {
    this.fancyMethod(); // Do something fancy with the model
});
var people = new Repository(appContext.collection("people"), { model: PersonModel });

people.save(person);
// beforeCreate(person)
// beforeSave(person)
// The model is created at db
// afterSave(person)
// afterCreate(person)

people.update(person, data);
// beforeUpdate(person, data)
// beforeSave(person, data)
// The model is updated at db
// afterSave(person, data)
// afterUpdate(person, data)

people.remove(person);
// beforeRemove(person)
// The model is deleted at db
// afterRemove(person)

Initialize

new FoxxRepository(collection, opts)
Create a new instance of Repository.
A Foxx Repository is always initialized with a collection object. You can get your collection object by asking your Foxx.Controller for it: the collection method takes the name of the collection (and will prepend the prefix of your application). It also takes two optional arguments:

  1. Model: The prototype of a model. If you do not provide it, it will default to Foxx.Model
  2. Prefix: You can provide the prefix of the application if you need it in your Repository (for some AQL queries probably)
    If the Model has any static methods named after the lifecycle events, they will automatically be registered as listeners to the events emitted by this repository.
    Examples
    instance = new Repository(appContext.collection("my_collection"));
    // or:
    instance = new Repository(appContext.collection("my_collection"), {
      model: MyModelPrototype
    });
    


    Example with listeners:

    var ValidatedModel = Model.extend({
      schema: {...}
    }, {
      beforeSave(modelInstance) {
     if (!modelInstance.valid) {
       throw new Error('Refusing to save: model is not valid!');
     }
      }
    });
    instance = new Repository(collection, {model: ValidatedModel});
    

Defining custom queries

You can define custom query methods using Foxx.createQuery and Foxx.Repository.extend.

For more details see the chapter on Foxx Queries.

Examples

Making a simple query in the repository and using it from the controller:

// in the repository
var Foxx = require("org/arangodb/foxx");

var TodosRepository = Foxx.Repository.extend({
    getPendingItems: Foxx.createQuery(
        'FOR todo IN my_todos FILTER todo.completed == false RETURN todo'
    )
});

// in the controller
ctrl.get("/", function(req, res) {
    req.json(todosRepository.getPendingItems());
});

It is also possible to supply parameters to the query:

// in the repository
TodosRepository.prototype.getPendingItemById = Foxx.createQuery({
    query: 'FOR todo IN my_todos FILTER todo.completed == false FILTER todo._key == @id RETURN todo',
    params: ['id']
});

// in the controller
ctrl.get("/:id", function(req, res) {
    var id = req.params("id");
    var rv = todosRepository.getPendingItemById(id);
    res.json(rv);
});

The list of results can also be transformed before returning it from the repository:

// in the repository
TodosRepository.prototype.getPendingItemById = Foxx.createQuery({
    query: 'FOR todo IN my_todos FILTER todo.completed == false FILTER todo._key == @id RETURN todo',
    params: ['id'],
    transform: function(results, extra) {
        for (var i = 0; i < results.length; i++) {
            results[i].extraProperty = extra;
        }
    }
});

// in the controller
ctrl.get("/:id", function(req, res) {
    var id = req.params("id");
    var extra = req.params("extra");
    var rv = todosRepository.getPendingItemById(id, extra);
    res.json(rv);
});

Attributes of a Repository

Collection

The wrapped ArangoDB collection object.

Model

The model of this repository. Formerly called “modelPrototype”.

Model schema

The schema of this repository’s model.

Prefix

The prefix of the application. This is useful if you want to construct AQL queries for example.

Defining indexes

Repository can take care of ensuring the existence of collection indexes for you. If you define indexes for a repository, instances of the repository will have access to additional index-specific methods like range or fulltext (see below).

The syntax for defining indexes is the same used in collection.ensureIndex.

Examples

var Foxx = require('org/arangodb/foxx');
var FulltextRepository = Foxx.Repository.extend({
    indexes: [
        {
            type: 'fulltext',
            fields: ['text'],
            minLength: 3
        }
    ]
});

Methods of a Repository

Adding entries to the repository

FoxxRepository#save(model)
Saves a model into the database. Expects a model. Will set the ID and Rev on the model. Returns the model.

Examples

repository.save(my_model);

Finding entries in the repository

FoxxRepository#byId(id)
Returns the model for the given ID (“collection/key”) or “key”.

Examples

var byIdModel = repository.byId('test/12411');
byIdModel.get('name');
<br />
var byKeyModel = repository.byId('12412');
byKeyModel.get('name');

FoxxRepository#byExample(example)
Returns an array of models for the given ID.

Examples

var myModel = repository.byExample({ amazing: true });
myModel[0].get('name');

FoxxRepository#firstExample(example)
Returns the first model that matches the given example.

Examples

var myModel = repository.firstExample({ amazing: true });
myModel.get('name');

FoxxRepository#all()
Returns an array of models that matches the given example. You can provide both a skip and a limit value.
Warning: ArangoDB doesn’t guarantee a specific order in this case, to make this really useful we have to explicitly provide something to order by.
Parameter

  • options (optional):
    • skip (optional): skips the first given number of models.
    • limit (optional): only returns at most the given number of models.

Examples

var myModel = repository.all({ skip: 4, limit: 2 });
myModel[0].get('name');

FoxxRepository#any()
Returns a random model from this repository (or null if there is none).

Examples

repository.any();

Removing entries from the repository

FoxxRepository#remove(model)
Remove the model from the repository. Expects a model.

Examples

repository.remove(myModel);

FoxxRepository#removeById(id)
Remove the document with the given ID (“collection/key”) or “key”. Expects an ID or key of an existing document.

Examples

repository.removeById('test/12121');
repository.removeById('12122');

FoxxRepository#removeByExample(example)
Find all documents that fit this example and remove them.

Examples

repository.removeByExample({ toBeDeleted: true });

Replacing entries in the repository

FoxxRepository#replace(model)
Find the model in the database by its _id and replace it with this version. Expects a model. Sets the revision of the model. Returns the model.

Examples

myModel.set('name', 'Jan Steemann');
repository.replace(myModel);

FoxxRepository#replaceById(id, object)
Find the item in the database by the given ID (“collection/key”) or “key” and replace it with the given object’s attributes.
If the object is a model, updates the model’s revision and returns the model.

Examples

repository.replaceById('test/123345', myNewModel);
repository.replaceById('123346', myNewModel);

FoxxRepository#replaceByExample(example, object)
Find every matching item by example and replace it with the attributes in the provided object.

Examples

repository.replaceByExample({ replaceMe: true }, myNewModel);

Updating entries in the repository

FoxxRepository#update(model, object)
Find the model in the database by its _id and update it with the given object. Expects a model. Sets the revision of the model and updates its properties. Returns the model.

Examples

repository.update(myModel, {name: 'Jan Steeman'});

FoxxRepository#updateById(id, object)
Find an item by ID (“collection/key”) or “key” and update it with the attributes in the provided object.
If the object is a model, updates the model’s revision and returns the model.

Examples

repository.updateById('test/12131', { newAttribute: 'awesome' });
repository.updateById('12132', { newAttribute: 'awesomer' });

FoxxRepository#updateByExample(example, object)
Find every matching item by example and update it with the attributes in the provided object.

Examples

repository.updateByExample({ findMe: true }, { newAttribute: 'awesome' });

FoxxRepository#exists(id)
Checks whether a model with the given ID or key exists.

Examples

repository.exists(model.get('_id'));

Counting entries in the repository

FoxxRepository#count()
Returns the number of entries in this collection.

Examples

repository.count();

Index-specific repository methods

FoxxRepository#range(attribute, left, right)
Returns all models in the repository such that the attribute is greater than or equal to left and strictly less than right.
For range queries it is required that a skiplist index is present for the queried attribute. If no skiplist index is present on the attribute, the method will not be available.
Parameter

  • attribute: attribute to query.
  • left: lower bound of the value range (inclusive).
  • right: upper bound of the value range (exclusive).

Examples

repository.range("age", 10, 13);

FoxxRepository#near(latitude, longitude, options)
Finds models near the coordinate (latitude, longitude). The returned list is sorted by distance with the nearest model coming first.
For geo queries it is required that a geo index is present in the repository. If no geo index is present, the methods will not be available.
Parameter

  • latitude: latitude of the coordinate.
  • longitude: longitude of the coordinate.
  • options (optional):
    • geo (optional): name of the specific geo index to use.
    • distance (optional): If set to a truthy value, the returned models will have an additional property containing the distance between the given coordinate and the model. If the value is a string, that value will be used as the property name, otherwise the name defaults to “distance”.
    • limit (optional): number of models to return. Defaults to 100.

Examples

repository.near(0, 0, {geo: "home", distance: true, limit: 10});

FoxxRepository#within(latitude, longitude, radius, options)
Finds models within the distance radius from the coordinate (latitude, longitude). The returned list is sorted by distance with the nearest model coming first.
For geo queries it is required that a geo index is present in the repository. If no geo index is present, the methods will not be available.
Parameter

  • latitude: latitude of the coordinate.
  • longitude: longitude of the coordinate.
  • radius: maximum distance from the coordinate.
  • options (optional):
    • geo (optional): name of the specific geo index to use.
    • distance (optional): If set to a truthy value, the returned models will have an additional property containing the distance between the given coordinate and the model. If the value is a string, that value will be used as the property name, otherwise the name defaults to “distance”.
    • limit (optional): number of models to return. Defaults to 100.

Examples

repository.within(0, 0, 2000 * 1000, {geo: "home", distance: true, limit: 10});

FoxxRepository#fulltext(attribute, query, options)
Returns all models whose attribute attribute matches the search query query.
In order to use the fulltext method, a fulltext index must be defined on the repository. If multiple fulltext indexes are defined on the repository for the attribute, the most capable one will be selected. If no fulltext index is present, the method will not be available.
Parameter

  • attribute: model attribute to perform a search on.
  • query: query to match the attribute against.
  • options (optional):
    • limit (optional): number of models to return. Defaults to all.

Examples

repository.fulltext("text", "word", {limit: 1});