Get all Entries by Matrix Lightswitch 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?
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 &amp; 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?