ArangoDB

Simple Queries

Simple queries can be used if the query condition is straight forward, i.e., a document reference, all documents, a query-by-example, or a simple geo query. In a simple query you can specify exactly one collection and one query criteria. In the following sections we describe the JavaScript shell interface for simple queries, which you can use within the ArangoDB shell and within actions and transactions. For other languages see the corresponding language API documentation.

If a query returns a cursor, then you can use hasNext and next to iterate over the result set or toArray to convert it to an array.

If the number of query results is expected to be big, it is possible to limit the amount of documents transferred between the server and the client to a specific value. This value is called batchSize. The batchSize can optionally be set before or when a simple query is executed. If the server has more documents than should be returned in a single batch, the server will set the hasMore attribute in the result. It will also return the id of the server-side cursor in the id attribute in the result. This id can be used with the cursor API to fetch any outstanding results from the server and dispose the server-side cursor afterwards.

The initial batchSize value can be set using the setBatchSize method that is available for each type of simple query, or when the simple query is executed using its execute method. If no batchSize value is specified, the server will pick a reasonable default value.



Queries


all()
Selects all documents of a collection and returns a cursor. You can use toArray, next, or hasNext to access the result. The result can be limited using the skip and limit operator.

Examples

Use toArray to get all documents at once:

arango> db.five.all().toArray();
[ { _id : 159896:1798296, _rev : 1798296, doc : 3 },
  { _id : 159896:1732760, _rev : 1732760, doc : 2 },
  { _id : 159896:1863832, _rev : 1863832, doc : 4 },
  { _id : 159896:1667224, _rev : 1667224, doc : 1 },
  { _id : 159896:1929368, _rev : 1929368, doc : 5 } ]

Use next to loop over all documents:

arango> var a = db.five.all();
arango> while (a.hasNext()) print(a.next());
{ _id : 159896:1798296, _rev : 1798296, doc : 3 }
{ _id : 159896:1732760, _rev : 1732760, doc : 2 }
{ _id : 159896:1863832, _rev : 1863832, doc : 4 }
{ _id : 159896:1667224, _rev : 1667224, doc : 1 }
{ _id : 159896:1929368, _rev : 1929368, doc : 5 }


collection.byExample(example)
Selects all documents of a collection that match the specified example and returns a cursor.

You can use toArray, next, or hasNext to access the result. The result can be limited using the skip and limit operator.

An attribute name of the form a.b is interpreted as attribute path, not as attribute. If you use

{ a : { c : 1 } }

as example, then you will find all documents, such that the attribute a contains a document of the form {c : 1 }. E.g., the document

{ a : { c : 1 }, b : 1 }

will match, but the document

{ a : { c : 1, b : 1 } }

will not.

However, if you use

{ a.c : 1 },

then you will find all documents, which contain a sub-document in a that has an attribute c of value 1. E.g., both documents

{ a : { c : 1 }, b : 1 } and

{ a : { c : 1, b : 1 } }

will match.


collection.byExample(path1, value1, ...)
As alternative you can supply a list of paths and values.

Examples

Use toArray to get all documents at once:

arango> db.users.all().toArray();
[ { "_id" : "553063885:554702285", "_rev" : 554702285, "id" : 323, "name" : "Peter" }, 
  { "_id" : "553063885:554636749", "_rev" : 554636749, "id" : 535, "name" : "Peter" }, 
  { "_id" : "553063885:554833357", "_rev" : 554833357, "id" : 25, "name" : "Vladimir" } ]

arango> db.users.byExample({ "id" : 323 }).toArray();
[ { "id" : 323, "name" : "Peter", "_id" : "553063885:554702285" } ]

arango> db.users.byExample({ "name" : "Peter" }).toArray();
[ { "id" : 323, "name" : "Peter", "_id" : "553063885:554702285" }, 
  { "id" : 535, "name" : "Peter", "_id" : "553063885:554636749" } ]

arango> db.users.byExample({ "name" : "Peter", "id" : 535 }).toArray();
[ { "id" : 535, "name" : "Peter", "_id" : "553063885:554636749" } ]

Use next to loop over all documents:

arango> var a = db.users.select( {"name" : "Peter" } );
arango> while (a.hasNext()) print(a.next());
{ "id" : 323, "name" : "Peter", "_id" : "553063885:554702285" } 
{ "id" : 535, "name" : "Peter", "_id" : "553063885:554636749" }


collection.firstExample(example)
Returns the a document of a collection that match the specified example or null. The example must be specified as paths and values. See byExample for details.


collection.firstExample(path1, value1, ...)
As alternative you can supply a list of paths and values.

Examples

arango> db.users.firstExample("name", 1237);
{ "_id" : "100225/83049373", "_rev" : 83049373, "name" : 1237 }


collection.range(attribute, left, right)
Selects all documents of a collection such that the attribute is greater or equal than left and strictly less than right.

You can use toArray, next, or hasNext to access the result. The result can be limited using the skip and limit operator.

An attribute name of the form a.b is interpreted as attribute path, not as attribute.

Examples

Use toArray to get all documents at once:

arangod> l = db.skip.range("age", 10, 13).toArray();
[
  { "_id" : "2097590/4260278", "_rev" : 4260278, "age" : 10 },
  { "_id" : "2097590/4325814", "_rev" : 4325814, "age" : 11 }, 
  { "_id" : "2097590/4391350", "_rev" : 4391350, "age" : 12 }
]


collection.count()
Returns the number of living documents in the collection.

Examples

arango> db.users.count();
10001


collection.toArray()
Converts the collection into an array of documents. Never use this call in a production environment.

Geo Queries

The ArangoDB allows to select documents based on geographic coordinates. In order for this to work, a geo-spatial index must be defined. This index will use a very elaborate algorithm to lookup neighbors that is a magnitude faster than a simple R* index.

In general a geo coordinate is a pair of latitude and longitude. This can either be an list with two elements like [-10, +30] (latitude first, followed by longitude) or an object like {lon: -10, lat: +30}. In order to find all documents within a given radius around a coordinate use the within operator. In order to find all documents near a given document use the near operator.

It is possible to define more than one geo-spatial index per collection. In this case you must give a hint using the geo operator which of indexes should be used in a query.


collection.near(latitude, longitude)

The default will find at most 100 documents near the coordinate (latitude, longitude). The returned list is sorted according to the distance, with the nearest document coming first. If there are near documents of equal distance, documents are chosen randomly from this set until the limit is reached. It is possible to change the limit using the limit operator.

In order to use the near operator, a geo index must be defined for the collection. This index also defines which attribute holds the coordinates for the document. If you have more then one geo-spatial index, you can use the geo operator to select a particular index.

Note:
near does not support negative skips. However, you can still use limit followed to skip.

collection.near(latitude, longitude).limit(limit)

Limits the result to limit documents instead of the default 100.

Note:
Unlike with multiple explicit limits, limit will raise the implicit default limit imposed by within.

collection.near(latitude, longitude).distance()

This will add an attribute distance to all documents returned, which contains the distance between the given point and the document in meter.


collection.near(latitude, longitude).distance(name)

This will add an attribute name to all documents returned, which contains the distance between the given point and the document in meter.

Examples

To get the nearst two locations:

arango> db.geo.near(0,0).limit(2).toArray();
[ { _id : 131840:24773376, _rev : 24773376, name : Name/0/0, loc : [ 0, 0 ] }, 
  { _id : 131840:22348544, _rev : 22348544, name : Name/-10/0, loc : [ -10, 0 ] } ]

If you need the distance as well, then you can use the distance operator:

arango> db.geo.near(0,0).distance().limit(2).toArray();
[ { _id : 131840:24773376, _rev : 24773376, distance : 0, name : Name/0/0, loc : [ 0, 0 ] },
  { _id : 131840:22348544, _rev : 22348544, distance : 1111949.3, name : Name/-10/0, loc : [ -10, 0 ] } ]


collection.within(latitude, longitude, radius)

This will find all documents with in a given radius around the coordinate (latitude, longitude). The returned list is sorted by distance.

In order to use the within operator, a geo index must be defined for the collection. This index also defines which attribute holds the coordinates for the document. If you have more then one geo-spatial index, you can use the geo operator to select a particular index.


collection.within(latitude, longitude, radius) .distance()

This will add an attribute _distance to all documents returned, which contains the distance between the given point and the document in meter.


collection.within(latitude, longitude, radius) .distance(name)

This will add an attribute name to all documents returned, which contains the distance between the given point and the document in meter.

Examples

To find all documents within a radius of 2000 km use:

arango> db.geo.within(0, 0, 2000 * 1000).distance().toArray();
[ { _id : 131840:24773376, _rev : 24773376, distance : 0, name : Name/0/0, loc : [ 0, 0 ] }, 
  { _id : 131840:24707840, _rev : 24707840, distance : 1111949.3, name : Name/0/-10, loc : [ 0, -10 ] },
  { _id : 131840:24838912, _rev : 24838912, distance : 1111949.3, name : Name/0/10, loc : [ 0, 10 ] },
  { _id : 131840:22348544, _rev : 22348544, distance : 1111949.3, name : Name/-10/0, loc : [ -10, 0 ] },
  { _id : 131840:27198208, _rev : 27198208, distance : 1111949.3, name : Name/10/0, loc : [ 10, 0 ] },
  { _id : 131840:22414080, _rev : 22414080, distance : 1568520.6, name : Name/-10/10, loc : [ -10, 10 ] },
  { _id : 131840:27263744, _rev : 27263744, distance : 1568520.6, name : Name/10/10, loc : [ 10, 10 ] },
  { _id : 131840:22283008, _rev : 22283008, distance : 1568520.6, name : Name/-10/-10, loc : [ -10, -10 ] },
  { _id : 131840:27132672, _rev : 27132672, distance : 1568520.6, name : Name/10/-10, loc : [ 10, -10 ] } ]


collection.geo(location)

The next near or within operator will use the specific geo-spatial index.


collection.geo(location, true)

The next near or within operator will use the specific geo-spatial index.


collection.geo(latitude, longitude)

The next near or within operator will use the specific geo-spatial index.

Examples

Assume you have a location stored as list in the attribute home and a destination stored in the attribute work. Than you can use the geo operator to select, which coordinates to use in a near query.

arango> for (i = -90;  i <= 90;  i += 10) {
.......>   for (j = -180;  j <= 180;  j += 10) {
.......>     db.complex.save({ name : "Name/" + i + "/" + j, 
.......>                       home : [ i, j ], 
.......>                       work : [ -i, -j ] });
.......>   }
.......> }

arango> db.complex.near(0, 170).limit(5);
exception in file '/simple-query' at 1018,5: an geo-index must be known

arango> db.complex.ensureGeoIndex("home");
arango> db.complex.near(0, 170).limit(5).toArray();
[ { _id : 48834092:74655276, _rev : 74655276, name : Name/0/170, home : [ 0, 170 ], work : [ 0, -170 ] },
  { _id : 48834092:74720812, _rev : 74720812, name : Name/0/180, home : [ 0, 180 ], work : [ 0, -180 ] }, 
  { _id : 48834092:77080108, _rev : 77080108, name : Name/10/170, home : [ 10, 170 ], work : [ -10, -170 ] },
  { _id : 48834092:72230444, _rev : 72230444, name : Name/-10/170, home : [ -10, 170 ], work : [ 10, -170 ] },
  { _id : 48834092:72361516, _rev : 72361516, name : Name/0/-180, home : [ 0, -180 ], work : [ 0, 180 ] } ]      

arango> db.complex.geo("work").near(0, 170).limit(5);
exception in file '/simple-query' at 1018,5: an geo-index must be known

arango> db.complex.ensureGeoIndex("work");
arango> db.complex.geo("work").near(0, 170).limit(5).toArray();
[ { _id : 48834092:72427052, _rev : 72427052, name : Name/0/-170, home : [ 0, -170 ], work : [ 0, 170 ] }, 
  { _id : 48834092:72361516, _rev : 72361516, name : Name/0/-180, home : [ 0, -180 ], work : [ 0, 180 ] }, 
  { _id : 48834092:70002220, _rev : 70002220, name : Name/-10/-170, home : [ -10, -170 ], work : [ 10, 170 ] }, 
  { _id : 48834092:74851884, _rev : 74851884, name : Name/10/-170, home : [ 10, -170 ], work : [ -10, 170 ] }, 
  { _id : 48834092:74720812, _rev : 74720812, name : Name/0/180, home : [ 0, 180 ], work : [ 0, -180 ] } ]

Pagination

If, for example, you display the result of a user search, then you are in general not interested in the completed result set, but only the first 10 or so documents. Or maybe the next 10 documents for the second page. In this case, you can the skip and limit operators. These operators work like LIMIT in MySQL.

skip used together with limit can be used to implement pagination. The skip operator skips over the first n documents. So, in order to create result pages with 10 result documents per page, you can use skip(n * 10).limit(10) to access the 10 documents on the n.th page. This result should be sorted, so that the pagination works in a predicable way.


query.limit(number)
Limits a result to the first number documents. Specifying a limit of 0 returns no documents at all. If you do not need a limit, just do not add the limit operator. The limit must be non-negative.

In general the input to limit should be sorted. Otherwise it will be unclear which documents are used in the result set.

Examples

arango> db.five.all().toArray();
[ { _id : 159896:1798296, _rev : 1798296, doc : 3 },
  { _id : 159896:1732760, _rev : 1732760, doc : 2 },
  { _id : 159896:1863832, _rev : 1863832, doc : 4 },
  { _id : 159896:1667224, _rev : 1667224, doc : 1 },
  { _id : 159896:1929368, _rev : 1929368, doc : 5 } ]

arango> db.five.all().limit(2).toArray();
[ { _id : 159896:1798296, _rev : 1798296, doc : 3 },
  { _id : 159896:1732760, _rev : 1732760, doc : 2 } ]

arango> db.five.all().limit(-2);
[ { _id : 159896:1667224, _rev : 1667224, doc : 1 },
  { _id : 159896:1929368, _rev : 1929368, doc : 5 } ]


query.skip(number)
Skips the first number documents. If number is positive, then skip the number of documents. If number is negative, then the total amount N of documents must be known and the results starts at position (N + number).

In general the input to limit should be sorted. Otherwise it will be unclear which documents are used in the result set.

Examples

arango> db.five.all().toArray();
[ { _id : 159896:1798296, _rev : 1798296, doc : 3 },
  { _id : 159896:1732760, _rev : 1732760, doc : 2 },
  { _id : 159896:1863832, _rev : 1863832, doc : 4 },
  { _id : 159896:1667224, _rev : 1667224, doc : 1 },
  { _id : 159896:1929368, _rev : 1929368, doc : 5 } ]

arango> db.five.all().skip(3).toArray();
[ { _id : 159896:1667224, _rev : 1667224, doc : 1 },
  { _id : 159896:1929368, _rev : 1929368, doc : 5 } ]

Sequential Access and Cursors


cursor.hasNext()
The hasNext operator returns true, then the cursor still has documents. In this case the next document can be accessed using the next operator, which will advance the cursor.

Examples

arango> var a = db.five.all();
arango> while (a.hasNext()) print(a.next());
{ _id : 159896:1798296, _rev : 1798296, doc : 3 }
{ _id : 159896:1732760, _rev : 1732760, doc : 2 }
{ _id : 159896:1863832, _rev : 1863832, doc : 4 }
{ _id : 159896:1667224, _rev : 1667224, doc : 1 }
{ _id : 159896:1929368, _rev : 1929368, doc : 5 }


cursor.next()
If the hasNext operator returns true, then the underlying cursor of the simple query still has documents. In this case the next document can be accessed using the next operator, which will advance the underlying cursor. If you use next on an exhausted cursor, then undefined is returned.

Examples

arango> db.five.all().next();
{ _id : 159896:1798296, _rev : 1798296, doc : 3 }


cursor.setBatchSize(number)
Sets the batch size for queries. The batch size determines how many results are at most transferred from the server to the client in one chunk.


cursor.getBatchSize()
Returns the batch size for queries. If the returned value is undefined, the server will determine a sensible batch size for any following requests.


query.execute(batchSize)
Executes a simple query. If the optional batchSize value is specified, the server will return at most batchSize values in one roundtrip. The batchSize cannot be adjusted after the query is first executed.

Note that there is no need to explicitly call the execute method if another means of fetching the query results is chosen. The following two approaches lead to the same result:

 result = db.users.all().toArray();
 q = db.users.all(); q.execute(); result = [ ]; while (q.hasNext()) { result.push(q.next()); }

The following two alternatives both use a batchSize and return the same result:

 q = db.users.all(); q.setBatchSize(20); q.execute(); while (q.hasNext()) { print(q.next()); }
 q = db.users.all(); q.execute(20); while (q.hasNext()) { print(q.next()); }


cursor.dispose()
If you are no longer interested in any further results, you should call dispose in order to free any resources associated with the cursor. After calling dispose you can no longer access the cursor.


cursor.count()
The count operator counts the number of document in the result set and returns that number. The count operator ignores any limits and returns the total number of documents found.

Note:
Not all simple queries support counting. In this case null is returned.

cursor.count(true)
If the result set was limited by the limit operator or documents were skiped using the skip operator, the count operator with argument true will use the number of elements in the final result set - after applying limit and skip.

Note:
Not all simple queries support counting. In this case null is returned.

Examples

Ignore any limit:

arango> db.five.all().limit(2).count();
5

Counting any limit or skip:

arango> db.five.all().limit(2).count(true);
2