Skip to content

Querying collections

You can perform queries on a collection to retrieve a set of resources that match the filters specified in the query.

The Connect ReST API use the Resource Query Language or RQL, to perform queries on a collection.

Note

This guide assumes you are somewhat familiar with RQL. If not, take a look at the RQL video tutorial here.

The ResourceSet object helps both to express RQL queries and to manipulate the resulting set of resources.

Create a ResourceSet object

A ResourceSet object can be created through the corresponding Collection object using the Collection.all() method to access all the resources of the collection:

products = client.products.all()

Or applying filter using the Collection.filter() method:

products = client.products.filter(status='published')

The ResourceSet will not be evaluated until you need the resources data, i.e. it does not make any HTTP call until needed, to help express more complex queries using method chaining like in the following example:

products = client.products.filter(status='published').order_by('-created')

Count results

To get the total number of resources represented by a ResourceSet you can use the ResourceSet.count() method.

no_of_published = client.products.filter(status='published').count()

or

total = client.products.all().count()

First result

To get the first resource represented by a ResourceSet you can use the ResourceSet.first() method.

first = client.products.all().first()

or

first = client.products.filter(status='published').first()

Filtering resources

The ResourceSet object offers three way to define your RQL query filters:

Using raw RQL filter expressions

You can express your filters using raw RQL expressions like in this example:

products = client.products.filter('ilike(name,*awesome*)', 'in(status,(draft,published))')

Arguments will be joined using the and logical operator.

Using kwargs and the __ (double underscore) notation

You can use the __ notation at the end of the name of the keyword argument to specify which RQL operator to apply:

products = client.products.filter(name__ilike='*awesome*', status__in=('draft', 'published'))

The lookups expressed through keyword arguments are and-ed togheter.

Chaning the filter method combine filters using and. Equivalent to the previous expression is to write:

products = client.products.filter(name__ilike='*awesome*').filter(status__in=('draft', 'published'))

The __ notation allow also to specify nested fields for lookups like:

products = client.products.filter(product__category__name__ilike='"*saas services*"')

Using the R object

The R object allows to create complex RQL filter expression.

The R constructor allows to specify lookups as keyword arguments the same way you do with the filter() method.

But it allows also to specify nested fields using the . notation:

flt = R().product.category.name.ilike('"*saas services*"')

products = client.products.filter(flt)

So an expression like:

flt = R().product.category.name.ilike('"*saas services*"')

products = client.products.filter(flt, status__in=('draft', 'published'))

will result in the following RQL query:

and(ilike(product.category.name,"*saas services*"),in(status,(draft,published)))

The R object also allows to join filter expressions using logical and and or and not using the &, | and and ~ bitwise operators:

query = (
    R(status='published') | R().category.name.ilike('*awesome*')
) & ~R(description__empty=True)

Other RQL operators

Searching

For endpoints that supports the RQL search operator you can specify your search term has shown below:

with_search = rs.search('term')

Ordering

To apply ordering you can specify the fields that have to be used to order the results:

ordered = rs.order_by('+field1', '-field2')

Any subsequent calls append other fields to the previous one.

So the previous statement can also be expressed with chaining:

ordered = rs.order_by('+field1').order_by('-field2')

RQL select

For collections that supports the select RQL operator you can specify the object to be selected/unselected the following way:

with_select = rs.select('+object1', '-object2')

Any subsequent calls append other select expression to the previous.

So the previous statement can also be expressed with chaining:

with_select = rs.select('+object1').select('-object2')