Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2019-07-19T15:41:30.417Z
Answers.LastActivityDate: 2019-07-19T15:41:30.417Z
Answers.UserDisplayName: gjhead
Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2019-07-09T01:45:40.257Z
Answers.LastActivityDate: 2019-07-09T05:08:27.743Z
Answers.LastEditDate: 2019-07-09T05:08:27.743Z
Answers.UserDisplayName: Parry Huang
Body: <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>
  
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2019-07-03T01:34:26.613Z
Comments.Text: 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?
Comments.UserDisplayName: Simon Kuran
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2019-07-05T20:14:41.320Z
Comments.Text: Yep.  It's correctly grabbing the categories.  It seems to be confused when it is filtering by the "investigatorTypes" as opposed to the "areaOfResearch".
Comments.UserDisplayName: gjhead
Tags: <craft3><elementquery>
Title: Entry Query relatedTo Two Categories
ThreadText: # 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() %}
  
  ```
  
  
  ---
  
  