AQL Queries¶
Query Builder is abstraction layer around AQL to work with it in more pythonic way.
Simplest start point is to use
arango.collection.Collection.query
.
Simple example:
from arango import collection as c
# create collection
c.test1.create()
c.test1.docs.create({"name": "John", "email": "john@example.com"})
c.test1.docs.create({"name": "Jane", "email": "jane@example.com"})
c.test1.query.filter("obj.name == 'John'").build_query()
c.test1.delete()
will generate AQL query:
FOR obj IN test
FILTER obj.name == 'John'
RETURN
obj
AQL Query Builder API¶
This API typically accesible via query
method of
collection instance.
Builder methods to generate AQL query:
-
class
arango.aql.
AQLQuery
(connection=None, collection=None, no_cache=False)¶ An abstraction layer to generate simple AQL queries.
-
bind
(**kwargs)¶ Bind some data to AQL Query. Technically it’s just a proxy to
arango.cursor.Cursor.bind
method which attach variables to theCursor
.It’s mostly for avoding any kind of query injetions.
data = c.test.query.filter("obj.name == @name")\ .bind(name="Jane")\ .execute().first assert data != None assert data.body["name"] == "Jane"
-
build_query
()¶ Build AQL query and return it as a string. This is good start to debug generated AQL queries.
-
collect
(*pairs, **kwargs)¶ Specify
COLLECT
operators, it’s possible to use it multiple timesCOLLECT variable-name = expression COLLECT variable-name = expression INTO groups
In python
c.test.query .collect("emails", "u.email") .collect("names", "u.name", into="eml") .result(emails="eml", names="names")
-
cursor
(**kwargs)¶ Method to provide custom arguments for
arango.cursor.Cursor
instance. All keywords arguments exceptbindVars
may be changed.
-
execute
(wrapper=None)¶ Execute query: create cursor, put binded variables and return instance of
arango.cursor.Cursor
object
-
filter
(condition)¶ Filter query by condition
condition
. It’s possible to add multiple filter expressions.FILTER condition
For exmaple code in python
c.test.query .filter("a==b && c==d") .filter("d == m")
-
iter
(name)¶ FOR
cycle temporary variable,variable-name
in AQL expression:FOR variable-name IN expression
-
let
(name, value)¶ Add
LET
operationLET variable-name = expression
-
limit
(count, offset=None)¶ Limit results with
count
items. By defaultoffset
is0
.query.limit(100, offset=10)
-
over
(expression)¶ expression
inFOR
cycleFOR variable-name IN expression
-
result
(*args, **kwargs)¶ Expression which will be added as
RETURN
of AQL. You can specify:- single name, like
q.result("u")
- named arguments, like
q.result(users="u", members="m")
which transform intoRETURN {users: u, members: m}
fields
named argument, likeq.result(fields={"key-a": "a"})
to work with names which are not supported by Python syntax.
- single name, like
-
sort
(*args)¶ Sort result by criterias from
args
.query.sort("u.email", "u.first_name DESC") .sort("u.last_name")
-
Helpers to work with query variables and functions.
-
arango.aql.
V
(name)¶ Factory for defining variables in requests. By default in functions arguments which are dicts all fields wrapped with double quoutes
"
. To specify members of variables defined aboveV
factory should be used.expect = 'MERGE({"user1": u.name}, {"user1": "name"})' assert F.MERGE( {"user1": V("u.name")}, {"user1": "name"}).build_query() == expect
-
class
arango.aql.
FuncFactory
¶ AQL Function factory. This is
F
object inarango.aql
module.from arango.aql import F c.test.query.over(F.PATH("a", "b", "c")).execute()
Execute query:
FOR obj IN PATH(a, b, c) RETURN obj
Making raw queries with AQL¶
Now it’s possible to querieng database by using Arango Query Language (AQL).
This functionality implementation based on HTTP Interface for AQL Query Cursors and provide lazy iterator over dataset and with ability to customize (wrap) result item by custom wrapper.
Alternative way to do such king of functionality is by using Documents REST Api which is not implemented in driver.
-
class
arango.cursor.
Cursor
(connection, query, count=True, batchSize=None, bindVars=None, wrapper=<bound method type.load of <class 'arango.document.Document'>>)¶ Work with Cursors in ArangoDB. At the moment, it’s common routine to work with AQL from this driver.
Note
the server will also destroy abandoned cursors automatically after a certain server-controlled timeout to avoid resource leakage.
query
- contains the query string to be executed (mandatory)count
- boolean flag that indicates whether the- number of documents found should be returned as “count” attribute in the result set (optional). Calculating the “count” attribute might have a performance penalty for some queries so this option is turned off by default.
batchSize
- maximum number of result documents to be- transferred from the server to the client in one roundtrip (optional). If this attribute is not set, a server-controlled default value will be used.
bindVars
- key/value list of bind parameters (optional).wrapper
- by default it’sDocument.load
- class, wrap result into
-
bind
(bind_vars)¶ Bind variables to the cursor
-
first
¶ Get first element from resultset
-
last
¶ Return last element from
current bulk
. It’s NOT last result in entire dataset.
Custom data wrapper for raw queries¶
It’s not necessary to wrap all documents within
Document
object. Cursor
do it by default
but you can provide custom wrapper by overriding
wrapper
argument during execution of
connection.query
method.
Note
Also it’s possible to provide custom wrapper via
arango.aql.AQLQuery.cursor
method during
building of the AQL query:
c.test1.query.cursor(wrapper=lambda conn, item: item)
.filter("obj.name == 'John'").build_query()
wrapper
should accept two arguments:
connection
- first argument, current connection instnaceitem
- dictionary with data provided from ArangoDB query
from arango import c
wrapper = lambda conn, item: item
c.collection.test.create()
c.collection.test.documents.create({"1": 2})
# create connection to database
for item in c.query("FOR d in test RETURN d", wrapper=wrapper):
item