Element queries are query builders that are tuned for fetching elements in Craft. They have several custom parameters, and they abstract away all the complexities of the actual SQL query needed to fetch the elements. Rather than raw data, they return element models.
You can create element queries in both PHP and Twig code. Here’s how:
Element Type | PHP | Twig |
---|---|---|
Assets | craft\elements\Asset::find() |
craft.assets() |
Categories | craft\elements\Category::find() |
craft.categories() |
Entries | craft\elements\Entry::find() |
craft.entries() |
Matrix blocks | craft\elements\MatrixBlock::find() |
craft.matrixBlocks() |
Tags | craft\elements\Tag::find() |
craft.tags() |
Users | craft\elements\User::find() |
craft.users() |
Once you’ve created an element query, you can set parameters on it.
The available parameters varies by element type. Here are the lists of parameters supported by Craft’s built-in element types:
The parameters should be set with chained method calls, like so:
use craft\elements\Entry;
$query = Entry::find()
->section('news')
->limit(10);
{% set query = craft.entries()
.section('news')
.limit(10) %}
You can also batch-set parameters like so:
use craft\elements\Entry;
$query = Entry::find();
Craft::configure($query, [
'section' => 'news',
'limit' => 10
]);
{% set query = craft.entries({
section: 'news',
limit: 10
}) %}
Once you’ve defined your parameters on the query, there are multiple methods available to execute it, depending on the data you need back.
Returns whether any elements match the query.
use craft\elements\Entry;
$exists = Entry::find()
->section('news')
->slug('hello-world')
->exists();
{% set exists = craft.entries()
.section('news')
.slug('hello-world')
.exists() %}
Returns the total number of elements that are matched by the query.
use craft\elements\Entry;
$count = Entry::find()
->section('news')
->count();
{% set count = craft.entries()
.section('news')
.count() %}
Returns all of the elements in an array.
{note} If the
asArray
param was set totrue
, then the elements will be represented as raw arrays, rather than element objects.
use craft\elements\Entry;
$entries = Entry::find()
->section('news')
->limit(10)
->all();
{% set entries = craft.entries()
.section('news')
.limit(10)
.all() %}
{tip} If you loop through an element query as if it were an array,
all()
will be called automatically for you, and you will actually be looping through its results.
Returns the first matching element, or null
if there isn’t one.
{note} If the
asArray
param was set totrue
, then the element will be represented as a raw array, rather than an element object.
use craft\elements\Entry;
$entry = Entry::find()
->section('news')
->slug('hello-world')
->one();
{% set entry = craft.entries()
.section('news')
.slug('hello-world')
.one() %}
Returns the n
th matching element, or null
if there isn’t one. Note that n
is 0-indexed, so nth(0)
will give you the first element, nth(1)
will give you the second, etc.
{note} If the
asArray
param was set totrue
, then the element will be represented as a raw array, rather than an element object.
use craft\elements\Entry;
$entry = Entry::find()
->section('news')
->nth(4);
{% set entry = craft.entries()
.section('news')
.nth(4) %}
Returns an array of the IDs of the matching elements.
use craft\elements\Entry;
$entryIds = Entry::find()
->section('news')
->ids();
{% set entryIds = craft.entries()
.section('news')
.ids() %}
Returns an array of all the first column’s values.
{note} By default the first column will be the elements’ IDs, but you can customize that with the
select()
param.
use craft\elements\Entry;
$uris = Entry::find()
->section('news')
->select('uri')
->column();
{% set uris = craft.entries()
.section('news')
.select('uri')
.column() %}
Returns the first column’s value of the first matching element.
{note} By default the first column will be the element’s ID, but you can customize that with the
select()
param.
use craft\elements\Entry;
$uri = Entry::find()
->section('news')
->slug('hello-world')
->select('uri')
->scalar();
{% set uri = craft.entries()
.section('news')
.slug('hello-world')
.select('uri')
.scalar() %}
The following methods will run an aggregate method on the first column of matching elements, and return the result:
sum()
– Returns the sum of all the values in the first columnaverage()
– Returns the average number of all the values in the first columnmin()
– Returns the minimum number of all the values in the first columnmax()
– Returns the maximum number of all the values in the first column
{note} By default the first column will be the elements’ IDs, but you can customize that with the
select()
param.
use craft\elements\Entry;
$sum = Entry::find()
->section('news')
->select('field_someNumberField')
->sum();
{% set sum = craft.entries()
.section('news')
.select('field_someNumberField')
.sum() %}