Filtering Matrix through field value and multiple relations I've the following situation:



Accommodations (entry)


title
description (textfield)
...
linkedTo (matrix block)

Sport (category)
targetGroup (category)
minimumAge (number)
maximumAge (number)





What I'm trying to do is fetch all entries (accommodations) related to a sport and targetGroup for a person of a certain age. E.g.: Entries for children with the age of 11 years in the targetGroup 'men/boys' and the sport 'football'.

Finding elements using relatedTo works for me, except I'm not able to filter the age. I'm pretty sure I'm doing something wrong here. I think it's not possible in craft to find textfield values via the relatedTo method, but the question is: How should I do this?

private function get ()
{
    $sport      = $this-&gt;findSelectedBySlug('football');
    $targetGroup    = $this-&gt;findSelectedBySlug('men-boys');
    $age            = 11;

    $wheres = [
        "and",
        [
            'targetElement' =&gt; $sport,
            'field' =&gt; "linkedTo.sport"
        ],
        [
            'targetElement' =&gt; $targetGroup,
            'field' =&gt; "linkedTo.targetGroup"
        ],
        [
            'targetElement' =&gt; "&lt;= {$age}",
            'field' =&gt; "linkedTo.minimumAge"
        ],
        [
            'targetElement' =&gt; "&gt; {$age}",
            'field' =&gt; "linkedTo.maximumAge"
        ]
    ];

    $criteria = craft()-&gt;elements-&gt;getCriteria(ElementType::Entry);
    $criteria-&gt;section = 'accomodations';
    $criteria-&gt;relatedTo = $wheres;

    return $criteria-&gt;find();
}
private function findSelectedBySlug ($slug)
{
    $criteria = craft()-&gt;elements-&gt;getCriteria(ElementType::Category);

    $criteria-&gt;slug = $slug;

    return $criteria-&gt;first();
}
You're right, this isn't possible with setting relatedTo parameters. But you can pass your ElementCriteriaModel (with all other parameters set) to the buildElementsQuery method, to prepare a DbCommand object. You can now modify the query as you need (→ Craft documentation for Database Queries).

Use join to bring in the "matrixblocks" table and also your Matrix field's content table "matrixcontent_mymatrixfield". Then add the min. and max age conditions with andWhere.

private function addAgeCriteria(ElementCriteriaModel $criteria, $age)
{
    $query = craft()-&gt;elements-&gt;buildElementsQuery($criteria);

    $params = array(
        ':age' =&gt; $age
    );

    $conditions = array('and',
        'matrixcontent_mymatrixfield.field_linkedTo_minimumAge &lt;= :age',
        'matrixcontent_mymatrixfield.field_linkedTo_maximumAge &gt;= :age'
    ),

    $query-&gt;andWhere($conditions, $params);

    $query-&gt;join('matrixblocks matrixblocks', 'matrixblocks.ownerId = entries.id');
    $query-&gt;join('matrixcontent_mymatrixfield matrixcontent_mymatrixfield', 'matrixcontent_mymatrixfield.elementId = matrixblocks.id');

    $results = $query-&gt;queryAll();

    return EntryModel::populateModels($results);
}