The cursor object of the JavaScript API
Cursor objects let you iterate over the results of executed AQL queries
The JavaScript API returns cursor objects when you use the following methods
of the db object from the @arangodb module:
db._query(...)db._createStatement(...).execute()
Both methods return a cursor object regardless of whether you call them client-side or server-side, but the underlying implementation differs:
- In arangosh, the cursor fetches the query results from the server, transferring them in batches as you iterate over the cursor.
- In server-side JavaScript contexts (such as Foxx services or
JavaScript Transactions), the results are by default computed and held in
memory on the server. If you enable the
streamquery option, the query is instead executed lazily, producing results as you iterate over the cursor.
If a query returns a cursor, then you can use the hasNext() and next()
methods to iterate over the results, or call toArray() right away to get an
array with all results.
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. You can set the
batchSize as an option when you execute a query with db._query() or when
you create a statement with db._createStatement(). If no batchSize value is
specified, the server picks a reasonable default value.
If the server has more documents than should be returned in a single batch,
the server sets the hasMore attribute in the result. It also
returns the ID of the server-side cursor in the id attribute in the response.
This ID can be used with the Cursor API to fetch any outstanding results from
the server and dispose the server-side cursor afterwards.
cursor.hasNext()
Checks whether there are more results available in the cursor.
If the hasNext() method returns true, then the cursor still has documents,
and you can retrieve the next one with the next() method. If it returns
false, the cursor is exhausted.
Example
Iterate over a query result, fetching one document at a time as long as there are more available:
var cursor = db._query("FOR x IN five RETURN x");
while (cursor.hasNext()) {
print(cursor.next());
}Show output
{
"_key" : "73727",
"_id" : "five/73727",
"_rev" : "_mLPD3aS---",
"name" : "one"
}
{
"_key" : "73729",
"_id" : "five/73729",
"_rev" : "_mLPD3aS--_",
"name" : "two"
}
{
"_key" : "73731",
"_id" : "five/73731",
"_rev" : "_mLPD3aW---",
"name" : "three"
}
{
"_key" : "73733",
"_id" : "five/73733",
"_rev" : "_mLPD3b----",
"name" : "four"
}
{
"_key" : "73735",
"_id" : "five/73735",
"_rev" : "_mLPD3bC---",
"name" : "five"
}cursor.next()
Returns the next result document.
As long as hasNext() returns true, there are more results available, and
each call to next() returns a single document and advances the cursor by one
position. In arangosh, the results are buffered locally in batches; when the
current batch is exhausted and more results are available on the server,
next() fetches the next batch, which requires a roundtrip to the server.
If you call next() on an exhausted cursor, then an error is thrown in
arangosh, whereas undefined is returned in server-side JavaScript contexts.
To avoid this, check the availability of results with hasNext() beforehand.
Example
Get the next document of a query result:
db._query("FOR x IN five RETURN x").next();Show output
{
"_key" : "73747",
"_id" : "five/73747",
"_rev" : "_mLPD3be---",
"name" : "one"
}cursor.toArray()
Returns all remaining result documents from the cursor as an array, and fully exhausts the cursor. In arangosh, this fetches any results that are not yet available locally from the server.
Example
Get all remaining documents of a query result as an array:
db._query("FOR x IN five RETURN x").toArray();Show output
[
{
"_key" : "73767",
"_id" : "five/73767",
"_rev" : "_mLPD3d----",
"name" : "one"
},
{
"_key" : "73769",
"_id" : "five/73769",
"_rev" : "_mLPD3d---_",
"name" : "two"
},
{
"_key" : "73771",
"_id" : "five/73771",
"_rev" : "_mLPD3dC---",
"name" : "three"
},
{
"_key" : "73773",
"_id" : "five/73773",
"_rev" : "_mLPD3dC--_",
"name" : "four"
},
{
"_key" : "73775",
"_id" : "five/73775",
"_rev" : "_mLPD3dC--A",
"name" : "five"
}
]cursor.dispose()
Disposes the cursor and its results.
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()
Returns the total number of documents in the result set, or undefined if the
number is not available.
The number remains the same regardless of how many result documents have already been fetched from the cursor.
In arangosh, this method only returns a number if the cursor was created with the
count cursor option enabled. Otherwise, it returns undefined.
Note that streaming cursors never return a count.
cursor.getExtra()
Returns the extra data stored for the cursor, or an empty object if there is none.
The extra data can include the following attributes:
stats: statistics about the query execution, such as the number of scanned documents (scannedFull,scannedIndex), the number of documents written (writesExecuted), the execution time, the peak memory usage, and afullCountvalue if thefullCountquery option was enabled.warnings: any warnings that occurred during the query execution.profile: profiling information if theprofilequery option was enabled.
Example
Get the extra information about a query, such as execution statistics and warnings:
db._query("FOR x IN 1..5 RETURN x").getExtra();Show output
{
"warnings" : [ ],
"stats" : {
"writesExecuted" : 0,
"writesIgnored" : 0,
"documentLookups" : 0,
"seeks" : 0,
"scannedFull" : 0,
"scannedIndex" : 0,
"searchParallelism" : 1,
"cursorsCreated" : 0,
"cursorsRearmed" : 0,
"cacheHits" : 0,
"cacheMisses" : 0,
"filtered" : 0,
"httpRequests" : 0,
"executionTime" : 0.00023061299998516915,
"peakMemoryUsage" : 0,
"intermediateCommits" : 0
}
}