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
This API typically accesible via query method of collection instance.
Builder methods to generate AQL query:
An abstraction layer to generate simple AQL queries.
Bind some data to AQL Query. Technically it’s just a proxy to arango.cursor.Cursor.bind method which attach variables to the Cursor.
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 AQL query and return it as a string. This is good start to debug generated AQL queries.
Specify COLLECT operators, it’s possible to use it multiple times
COLLECT 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")
Method to provide custom arguments for arango.cursor.Cursor instance. All keywords arguments except bindVars may be changed.
Execute query: create cursor, put binded variables and return instance of arango.cursor.Cursor object
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")
FOR cycle temporary variable, variable-name in AQL expression:
FOR variable-name IN expression
Add LET operation
LET variable-name = expression
Limit results with count items. By default offset is 0.
query.limit(100, offset=10)
expression in FOR cycle
FOR variable-name IN expression
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 into RETURN {users: u, members: m}
- fields named argument, like q.result(fields={"key-a": "a"}) to work with names which are not supported by Python syntax.
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.
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 above V factory should be used.
expect = 'MERGE({"user1": u.name}, {"user1": "name"})'
assert F.MERGE(
{"user1": V("u.name")},
{"user1": "name"}).build_query() == expect
AQL Function factory. This is F object in arango.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
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.
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)
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.
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).
class, wrap result into
Bind variables to the cursor
Get first element from resultset
Return last element from current bulk. It’s NOT last result in entire dataset.
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 instnace
- item - 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