<p>After a ton of headbanging (and not the fun heavy-metal kind) I ended up following the answer in this post, and it seems to be working!</p>

<p><a href="https://craftcms.stackexchange.com/questions/25739/craft-3-multi-category-and-field-search">Craft 3 Multi Category and Field Search</a></p>

CC BY-SA 4.0
2019-07-19T15:41:30.417Z
2019-07-19T15:41:30.417Z
gjhead
<p>First, I might over complicate things. Maybe there is a simple solution by using: 
<a href="https://docs.craftcms.com/v3/relations.html#passing-multiple-relation-criteria" rel="nofollow noreferrer">https://docs.craftcms.com/v3/relations.html#passing-multiple-relation-criteria</a></p>

<p>But my project has a complex query built in. So I did a custom db query class. And here is one of them might working for you. </p>

<p>If you know how to create a twig function in craft 3 in modules, the following code will make sense to you. If you don't know how to do it. Here is the link how to do it <a href="https://docs.craftcms.com/v3/extend/extending-twig.html#register-a-twig-extension" rel="nofollow noreferrer">https://docs.craftcms.com/v3/extend/extending-twig.html#register-a-twig-extension</a>.</p>

<pre><code>    /**
     * This function is a twig extension

     * @param $IdArray      array           the array of element ids used for related to 
     *                                      you can join as many ids you want to.
     *                                      e.g. [
     *                                              [
     *                                                "or", ["1234","23123"]
     *                                              ],
     *                                              [
     *                                                "and", ["234","1232","12332"]
     *                                              ],
     *                                              ...
     *                                            ]
     * @return object                       craft element query object
     */
    public function elementMultiRelatedTo($elementQuery, $IdArray=[]){
        if($IdArray!=[]&amp;&amp;isset($IdArray[0])&amp;&amp;is_array($IdArray[0])){
            foreach ($IdArray as $key=&gt;$value){
                if(isset($value[0])&amp;&amp;is_string($value[0])&amp;&amp;isset($value[1])&amp;&amp;is_array($value[1])&amp;&amp;$value[1]!=[]){
                    if($value[0]=="or"){
                        $elementQuery = $elementQuery-&gt;orWhere($this-&gt;multipleRelatedToQuery($value[1]));
                    }elseif($value[0] == "and"){
                        $elementQuery = $elementQuery-&gt;andWhere($this-&gt;multipleRelatedToQuery($value[1]));
                    }
                }
            }
        }

        return $elementQuery;
    }

    /**
     *
     * @param $id
     * @return \yii\db\Expression
     */
    public function multipleRelatedToQuery($id){
        $sourceString = "";
        $targetString = "";
        if($id==[""]||$id==""||$id==[]){
            return new \yii\db\Expression("1");
        }
        if(is_array($id)){
            foreach($id as $key =&gt; $v){
                if($key == 0){
                    $sourceString = "`sources2`.`sourceId` = '$v'";
                    $targetString = "`targets2`.`targetId` = '$v'";
                }else{
                    $sourceString = $sourceString . " OR `sources2`.`sourceId` = '$v'";
                    $targetString = $targetString . " OR `targets2`.`targetId` = '$v'";
                }

            }
        }else{
            $sourceString = "`sources2`.`sourceId` = '$id'";
            $targetString = "`targets2`.`targetId` = '$id'";
        }

        return new \yii\db\Expression("
        (
            `elements`.`id` IN 
            (
                SELECT 
                    `sources2`.`targetId`
                FROM
                    `craft_relations` `sources2`
                WHERE
                    $sourceString
            )
            OR `elements`.`id` IN 
            (
                SELECT 
                    `targets2`.`sourceId`
                FROM
                    `craft_relations` `targets2`
                WHERE
                    $targetString
            )
        )");
    }
</code></pre>

<p>Then in twig</p>

<pre><code>{% set typeQuery = craft.app.request.getParam('t') %}
{% set areaQuery = craft.app.request.getParam('a') %}

{% set cat1 = craft.categories.group('investigatorTypes').slug(typeQuery).one().id %}
{% set cat2 = craft.categories.group('areaOfResearch').slug(areaQuery).one().id %}

{% set researchers = craft.entries()
    .section('investigatorBios')
    .orderBy('bioLastName asc')
    .limit(12)
%}

{# here cat1 and cat2 is not array, make sure put them in [] #}
{# if you want more than one id, you can try ".ids()" instead of ".one().id" #}

{% set researchers = elementMultiRelatedTo(resaerchers, 
[
  [
     "and",
     [cat1]
  ],
  [
     "and",
     [cat2]
  ]
]) %}
{% researchersArray = researchers.all() %}
</code></pre>

CC BY-SA 4.0
2019-07-09T01:45:40.257Z
2019-07-09T05:08:27.743Z
2019-07-09T05:08:27.743Z
Parry Huang
<p>This has to be something that is easy, but I've been beating my head on my desk for a a few hours with this.  Most solutions I have come across are way to complex - when all I need to do is query a section for all entries that appear in two categories.</p>

<p>I'm pulling in the slugs via url,</p>

<p>ex: domain.com/investigators?t=primary&amp;a=pregnancy-newborn-medicine</p>

<p>Then querying like so:</p>

<pre><code>{% set typeQuery = craft.app.request.getParam('t') %}
{% set areaQuery = craft.app.request.getParam('a') %}

{% set cat1 = craft.categories.group('investigatorTypes').slug(typeQuery).one() %}
{% set cat2 = craft.categories.group('areaOfResearch').slug(areaQuery).one() %}

{% set researchers = craft.entries()
    .section('investigatorBios')
    .relatedTo(['and', 
        {element: cat1},
        {element: cat2}
    ])
    .orderBy('bioLastName asc')
    .limit(12)
%}  
</code></pre>

<p>What am I doing wrong?<br>
Slugs match the respective categories in the groups.  There are only two types in the investigatorTypes I can query for - one returns all of them, and the other returns none.</p>

<p>Am I overlooking something obvious?</p>

<p>Thanks in advance, friends.</p>

CC BY-SA 4.0
2019-07-03T01:34:26.613Z
Your code is working for me. I didn't use multiple category groups though, doubt that's the problem. Have you tried outputting `{{ cat1.title }}{{ cat2.title }}` to confirm that you're correctly grabbing the categories?
Simon Kuran
CC BY-SA 4.0
2019-07-05T20:14:41.320Z
Yep.  It's correctly grabbing the categories.  It seems to be confused when it is filtering by the "investigatorTypes" as opposed to the "areaOfResearch".
gjhead
<craft3><elementquery>
Entry Query relatedTo Two Categories
# Entry Query relatedTo Two Categories

(Asked by: username_0 on 2019-07-02)

This has to be something that is easy, but I've been beating my head on my desk for a a few hours with this.  Most solutions I have come across are way to complex - when all I need to do is query a section for all entries that appear in two categories.
I'm pulling in the slugs via url,
ex: domain.com/investigators?t=primary&a=pregnancy-newborn-medicine
Then querying like so:
{% set typeQuery = craft.app.request.getParam('t') %}
{% set areaQuery = craft.app.request.getParam('a') %}

{% set cat1 = craft.categories.group('investigatorTypes').slug(typeQuery).one() %}
{% set cat2 = craft.categories.group('areaOfResearch').slug(areaQuery).one() %}

{% set researchers = craft.entries()
    .section('investigatorBios')
    .relatedTo(['and', 
        {element: cat1},
        {element: cat2}
    ])
    .orderBy('bioLastName asc')
    .limit(12)
%}  

What am I doing wrong?
Slugs match the respective categories in the groups.  There are only two types in the investigatorTypes I can query for - one returns all of them, and the other returns none.
Am I overlooking something obvious?
Thanks in advance, friends.

**Tags:** craft3, elementquery

> **Comments:**
> **username_1**: Your code is working for me. I didn't use multiple category groups though, doubt that's the problem. Have you tried outputting `{{ cat1.title }}{{ cat2.title }}` to confirm that you're correctly grabbing the categories?  
> **username_0**: Yep.  It's correctly grabbing the categories.  It seems to be confused when it is filtering by the "investigatorTypes" as opposed to the "areaOfResearch".  

---

## 2 answers

### Answer by username_0 on 2019-07-19. Score: 2

After a ton of headbanging (and not the fun heavy-metal kind) I ended up following the answer in this post, and it seems to be working!

[Craft 3 Multi Category and Field Search](https://craftcms.stackexchange.com/questions/25739/craft-3-multi-category-and-field-search)


---

### Answer by username_2 on 2019-07-09. Score: 2

First, I might over complicate things. Maybe there is a simple solution by using: 
https://docs.craftcms.com/v3/relations.html#passing-multiple-relation-criteria
But my project has a complex query built in. So I did a custom db query class. And here is one of them might working for you. 
If you know how to create a twig function in craft 3 in modules, the following code will make sense to you. If you don't know how to do it. Here is the link how to do it https://docs.craftcms.com/v3/extend/extending-twig.html#register-a-twig-extension.
    /**
     * This function is a twig extension

     * @param $IdArray      array           the array of element ids used for related to 
     *                                      you can join as many ids you want to.
     *                                      e.g. [
     *                                              [
     *                                                "or", ["1234","23123"]
     *                                              ],
     *                                              [
     *                                                "and", ["234","1232","12332"]
     *                                              ],
     *                                              ...
     *                                            ]
     * @return object                       craft element query object
     */
    public function elementMultiRelatedTo($elementQuery, $IdArray=[]){
        if($IdArray!=[]&&isset($IdArray[0])&&is_array($IdArray[0])){
            foreach ($IdArray as $key=>$value){
                if(isset($value[0])&&is_string($value[0])&&isset($value[1])&&is_array($value[1])&&$value[1]!=[]){
                    if($value[0]=="or"){
                        $elementQuery = $elementQuery->orWhere($this->multipleRelatedToQuery($value[1]));
                    }elseif($value[0] == "and"){
                        $elementQuery = $elementQuery->andWhere($this->multipleRelatedToQuery($value[1]));
                    }
                }
            }
        }

        return $elementQuery;
    }

    /**
     *
     * @param $id
     * @return \yii\db\Expression
     */
    public function multipleRelatedToQuery($id){
        $sourceString = "";
        $targetString = "";
        if($id==[""]||$id==""||$id==[]){
            return new \yii\db\Expression("1");
        }
        if(is_array($id)){
            foreach($id as $key => $v){
                if($key == 0){
                    $sourceString = "`sources2`.`sourceId` = '$v'";
                    $targetString = "`targets2`.`targetId` = '$v'";
                }else{
                    $sourceString = $sourceString . " OR `sources2`.`sourceId` = '$v'";
                    $targetString = $targetString . " OR `targets2`.`targetId` = '$v'";
                }

            }
        }else{
            $sourceString = "`sources2`.`sourceId` = '$id'";
            $targetString = "`targets2`.`targetId` = '$id'";
        }

        return new \yii\db\Expression("
        (
            `elements`.`id` IN 
            (
                SELECT 
                    `sources2`.`targetId`
                FROM
                    `craft_relations` `sources2`
                WHERE
                    $sourceString
            )
            OR `elements`.`id` IN 
            (
                SELECT 
                    `targets2`.`sourceId`
                FROM
                    `craft_relations` `targets2`
                WHERE
                    $targetString
            )
        )");
    }

Then in twig
{% set typeQuery = craft.app.request.getParam('t') %}
{% set areaQuery = craft.app.request.getParam('a') %}

{% set cat1 = craft.categories.group('investigatorTypes').slug(typeQuery).one().id %}
{% set cat2 = craft.categories.group('areaOfResearch').slug(areaQuery).one().id %}

{% set researchers = craft.entries()
    .section('investigatorBios')
    .orderBy('bioLastName asc')
    .limit(12)
%}

{# here cat1 and cat2 is not array, make sure put them in [] #}
{# if you want more than one id, you can try ".ids()" instead of ".one().id" #}

{% set researchers = elementMultiRelatedTo(resaerchers, 
[
  [
     "and",
     [cat1]
  ],
  [
     "and",
     [cat2]
  ]
]) %}
{% researchersArray = researchers.all() %}


---

