<p>Fetching entries by a Matrix block field value is actually quite complicated, and not possible to do in a single query – at least not using built in services like <code>craft.entries</code>.</p>

<p>Your idea of pulling all entries and looping through would work – but this kind of "brute force" solution might not scale that well, performance wise.</p>

<p>A better idea might be to first pull all the <code>space</code> Matrix blocks that have a <code>true</code> value for the <code>isAvailable</code> field, and then pull any entry belonging to the <code>buildings</code> section that has a relation at least one of those blocks.</p>

<p>Unfortunately, unlike the EntriesService (i.e. <code>craft.entries</code>), Craft doesn't expose the <a href="https://buildwithcraft.com/classreference/services/MatrixService" rel="nofollow">MatrixService</a> to Twig, making the above hard to accomplish in a template.</p>

<p>For a clean &amp; effective solution to this problem, I'd look to the excellent <a href="https://github.com/low/lowblocks" rel="nofollow">Low Blocks plugin</a>.</p>

<p>With Low Blocks, you'll be able to pull all <code>space</code> blocks with a <code>true</code> value for <code>isAvailable</code> like this:</p>

<pre><code>{% set spacesMatrixField = craft.fields.getFieldByHandle('spaces') %}
{% set spaceMatrixBlocks = craft.lowblocks.blocks.fieldId(spacesMatrixField.id).type('space').isAvailable('1') %}
</code></pre>

<p>After that, we can loop on the <code>matrixBlocks</code> variable in order to create an array containing the IDs of the entries "owning" these Matrix blocks:</p>

<pre><code>{% set buildingEntryIds = [] %}
{% for block in spaceMatrixBlocks %}
    {% set buildingEntryIds = buildingEntryIds|merge([block.owner.id]) %}
{% endfor %}
</code></pre>

<p>And finally, we pull the entries using the <code>buildingEntryIds</code> array variable as the parameter to the <code>id</code> argument:</p>

<pre><code>{% set entries = craft.entries.section('buildings').id(buildingEntryIds).limit(null) %}
</code></pre>

<p>Here's everything together, for cohesion:</p>

<pre><code>{# Get Matrix blocks #}
{% set spacesMatrixField = craft.fields.getFieldByHandle('spaces') %}
{% set spaceMatrixBlocks = craft.lowblocks.blocks.fieldId(spacesMatrixField.id).type('space').isAvailable('1') %}

{# Get entry IDs #}
{% set buildingEntryIds = [] %}
{% for block in spaceMatrixBlocks %}
    {% set buildingEntryIds = buildingEntryIds|merge([block.owner.id]) %}
{% endfor %}

{# Get entries #}
{% set entries = craft.entries.section('buildings').id(buildingEntryIds).limit(null) %}
</code></pre>

<p>That should hopefully do the trick. If you're interested though, here's some more info on why your first attempt wouldn't work:</p>

<p>First, I'd like to point out that its important to realize that each chained "segment" (such as <code>section</code> or <code>isAvailable</code>) in a call to <code>craft.entries</code> in a template actually ends up as an attribute of an ElementCriteriaModel (an object Craft constructs to query the database). This means that</p>

<pre><code>craft.entries.section('buildings').spaces.space.isAvailable('1').find
</code></pre>

<p>is actually the same as</p>

<pre><code>craft.entries({
    section : 'buildings',
    spaces : null,
    space : null,
    isAvailable : '1'
})
</code></pre>

<p>It should be fairly obvious why this query won't do what you want; Craft has no idea that <code>spaces.space.isAvailable</code> is actually the "path" to a certain Matrix block type's field, and will consider each of those segments (<code>spaces</code>, <code>space</code> and <code>isAvailable</code>) as a separate attribute/argument.</p>

<p>Aside from the syntax issue, the real reason why you'll never be able to use something like <code>spaces.space.isAvailable</code> in a <code>craft.entries</code> query is that Matrix blocks aren't just regular, nested fields, but elements unto themselves (just like entries, categories or assets). Also, for any single entry there can be an indefinite number of instances of each block type. If you have multiple <code>space</code> blocks for a single entry, some with a <code>false</code> <code>isAvailable</code> value and some with <code>true</code>, how would Craft know if the entry should be returned or not?</p>

CC BY-SA 3.0
2015-11-22T15:03:15.147Z
2015-11-22T15:03:15.147Z
Mats Mikkel Rummelhoff
<p>This is a perfect use case for the <a href="https://github.com/aelvan/Preparse-Field-Craft" rel="nofollow">Preparse plugin</a>. Install the plugin and add a Prepase field to your Entry Type and name it <code>spaceAvailable</code> for example. Configure the field to fetch the first <code>space</code> Matrix block it can find in your <code>spaces</code> Matrix and make it return the value of its <code>isAvailable</code> lightswitch.</p>

<pre><code>{% set firstSpaceBlock = entry.spaces.type('space').first() %}
{{- firstSpaceBlock ? firstSpaceBlock.isAvailable : 0 }}
</code></pre>

<p>This basically copies that value to the root level of your entry model (it does so on every entry save!), and you can now query for the entries you're interested in with a single criteria model.</p>

<pre><code>{% set entries = craft.entries.spaceAvailable(1).limit(null) %}
</code></pre>

CC BY-SA 3.0
2015-11-23T07:59:18.067Z
2015-11-23T07:59:18.067Z
carlcs
<p>I would like to fetch all entries in a section according to a Lightswitch value inside of a matrix field. Initially I tried:</p>

<pre><code>craft.entries.section('buildings').spaces.space.isAvailable('1').find
</code></pre>

<p>but this doesn't pull any results. Is this even possible in a single query? Or do I need to get all entries from the section first, and then loop over them in order to determine if the Lightswitch has the desired value?</p>

<matrix><search>
Get all Entries by Matrix Lightswitch
# Get all Entries by Matrix Lightswitch

(Asked by: username_0 on 2015-11-21)

I would like to fetch all entries in a section according to a Lightswitch value inside of a matrix field. Initially I tried:
craft.entries.section('buildings').spaces.space.isAvailable('1').find

but this doesn't pull any results. Is this even possible in a single query? Or do I need to get all entries from the section first, and then loop over them in order to determine if the Lightswitch has the desired value?

**Tags:** matrix, search

---

## 2 answers

### Answer by username_1 on 2015-11-22. Score: 2 | Accepted answer

Fetching entries by a Matrix block field value is actually quite complicated, and not possible to do in a single query – at least not using built in services like craft.entries.
Your idea of pulling all entries and looping through would work – but this kind of "brute force" solution might not scale that well, performance wise.
A better idea might be to first pull all the space Matrix blocks that have a true value for the isAvailable field, and then pull any entry belonging to the buildings section that has a relation at least one of those blocks.
Unfortunately, unlike the EntriesService (i.e. craft.entries), Craft doesn't expose the MatrixService to Twig, making the above hard to accomplish in a template.
For a clean & effective solution to this problem, I'd look to the excellent Low Blocks plugin.
With Low Blocks, you'll be able to pull all space blocks with a true value for isAvailable like this:
{% set spacesMatrixField = craft.fields.getFieldByHandle('spaces') %}
{% set spaceMatrixBlocks = craft.lowblocks.blocks.fieldId(spacesMatrixField.id).type('space').isAvailable('1') %}

After that, we can loop on the matrixBlocks variable in order to create an array containing the IDs of the entries "owning" these Matrix blocks:
{% set buildingEntryIds = [] %}
{% for block in spaceMatrixBlocks %}
    {% set buildingEntryIds = buildingEntryIds|merge([block.owner.id]) %}
{% endfor %}

And finally, we pull the entries using the buildingEntryIds array variable as the parameter to the id argument:
{% set entries = craft.entries.section('buildings').id(buildingEntryIds).limit(null) %}

Here's everything together, for cohesion:
{# Get Matrix blocks #}
{% set spacesMatrixField = craft.fields.getFieldByHandle('spaces') %}
{% set spaceMatrixBlocks = craft.lowblocks.blocks.fieldId(spacesMatrixField.id).type('space').isAvailable('1') %}

{# Get entry IDs #}
{% set buildingEntryIds = [] %}
{% for block in spaceMatrixBlocks %}
    {% set buildingEntryIds = buildingEntryIds|merge([block.owner.id]) %}
{% endfor %}

{# Get entries #}
{% set entries = craft.entries.section('buildings').id(buildingEntryIds).limit(null) %}

That should hopefully do the trick. If you're interested though, here's some more info on why your first attempt wouldn't work:
First, I'd like to point out that its important to realize that each chained "segment" (such as section or isAvailable) in a call to craft.entries in a template actually ends up as an attribute of an ElementCriteriaModel (an object Craft constructs to query the database). This means that
craft.entries.section('buildings').spaces.space.isAvailable('1').find

is actually the same as
craft.entries({
    section : 'buildings',
    spaces : null,
    space : null,
    isAvailable : '1'
})

It should be fairly obvious why this query won't do what you want; Craft has no idea that spaces.space.isAvailable is actually the "path" to a certain Matrix block type's field, and will consider each of those segments (spaces, space and isAvailable) as a separate attribute/argument.
Aside from the syntax issue, the real reason why you'll never be able to use something like spaces.space.isAvailable in a craft.entries query is that Matrix blocks aren't just regular, nested fields, but elements unto themselves (just like entries, categories or assets). Also, for any single entry there can be an indefinite number of instances of each block type. If you have multiple space blocks for a single entry, some with a false isAvailable value and some with true, how would Craft know if the entry should be returned or not?


---

### Answer by username_2 on 2015-11-23. Score: 2

This is a perfect use case for the Preparse plugin. Install the plugin and add a Prepase field to your Entry Type and name it spaceAvailable for example. Configure the field to fetch the first space Matrix block it can find in your spaces Matrix and make it return the value of its isAvailable lightswitch.
{% set firstSpaceBlock = entry.spaces.type('space').first() %}
{{- firstSpaceBlock ? firstSpaceBlock.isAvailable : 0 }}

This basically copies that value to the root level of your entry model (it does so on every entry save!), and you can now query for the entries you're interested in with a single criteria model.
{% set entries = craft.entries.spaceAvailable(1).limit(null) %}


---

