Answers.Body: <p>When I understand Brandon correctly in this answer <a href="https://craftcms.stackexchange.com/a/6867/125">Query for blocks across Block Types using the new field parameter?</a>, it's not possible to set up what you want with a criteria model.</p>
  
  <p>What you can do though is to add additional custom query conditions to the <code>dbCommand</code> after running the criteria model through the <code>buildElementsQuery</code> function.</p>
  
  <pre><code>public function getMatrixBlocks($matrixFieldId, $fieldValue)
  {
      $criteria = craft()-&gt;elements-&gt;getCriteria(ElementType::MatrixBlock);
      $criteria-&gt;fieldId = $matrixFieldId;
  
      $dbCommand = craft()-&gt;elements-&gt;buildElementsQuery($criteria);
  
      $params = array(
          ':myFieldHandle' =&gt; $fieldValue,
      );
  
      $conditions = array('or',
          'content.field_myBlockTypeA_myFieldHandle=:myFieldHandle',
          'content.field_myBlockTypeB_myFieldHandle=:myFieldHandle',
      );
  
      $dbCommand-&gt;andWhere($conditions, $params);
  
      return $dbCommand-&gt;queryAll();
  }
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-03-25T14:32:30.930Z
Answers.Text: Perfect answer!
Answers.UserDisplayName: Fred Carlsen
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-03-25T14:49:25.930Z
Answers.Text: Related to this, how do I repopulate Asset/relation fields when saving this block again?
Answers.UserDisplayName: Fred Carlsen
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-03-25T15:10:12.693Z
Answers.Text: Fixed it thanks to this: http://craftcms.stackexchange.com/questions/11137/categories-field-is-losing-its-value-when-programmatically-updating-other-fields/11146#11146
Answers.UserDisplayName: Fred Carlsen
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-03-25T14:12:44.693Z
Answers.LastActivityDate: 2016-03-25T14:12:44.693Z
Answers.LastEditDate: 2017-04-13T12:50:59.930Z
Answers.UserDisplayName: carlcs
Body: <p>I'm trying to query against a specific field value in a Matrix field with multiple block types, and I've tried multiple approaches with no success. It either returns 0 results, or all blocks regardless of type.</p>
  
  <p>The use case is that Snipcart is doing a callback with the ordered items and their skus. I got the different product variants in a Matrix fields, and every variant has its own sku. The field have two block types. I want to find the correct product variant and reduce the available stock.</p>
  
  <p>The simplest approach is this:</p>
  
  <pre class="lang-php prettyprint-override"><code>$criteria      = craft()-&gt;elements-&gt;getCriteria(ElementType::MatrixBlock);
  $criteria-&gt;sku = 'JW';
  </code></pre>
  
  <p>I figured out that it won't join the content table if you don't specify a fieldId, and you also need a typeId.</p>
  
  <pre class="lang-php prettyprint-override"><code>$criteria      = craft()-&gt;elements-&gt;getCriteria(ElementType::MatrixBlock);
  $criteria-&gt;fieldId = $fieldId;
  $criteria-&gt;typeId = $typeId;
  $criteria-&gt;sku = 'JW';
  </code></pre>
  
  <p>What happens then is that it's seem to do the correct query, but with a AND query for the field on both block types (even though I have defined a typeId):</p>
  
  <pre><code>system.db.CDbCommand.query(SELECT `elements`.`id`, `matrixblocks`.`fieldId`, `matrixblocks`.`ownerId`, `matrixblocks`.`ownerLocale`, `matrixblocks`.`typeId`, `matrixblocks`.`sortOrder`
  FROM `craft_elements` `elements`
  JOIN `craft_elements_i18n` `elements_i18n` ON elements_i18n.elementId = elements.id
  JOIN `craft_matrixcontent_colorsandtextures` `content` ON content.elementId = elements.id
  JOIN `craft_matrixblocks` `matrixblocks` ON matrixblocks.id = elements.id
  WHERE (((((((elements_i18n.locale = :locale) AND (content.locale = :locale)) AND (elements.archived = 0)) AND (elements.enabled = 1)) AND (elements_i18n.enabled = 1)) AND (content.field_texture_sku=:contentfield_texture_sku1)) AND (content.field_color_sku=:contentfield_color_sku1)) AND (matrixblocks.fieldId=:matrixblocksfieldId1)
  GROUP BY `elements`.`id`
  ORDER BY `matrixblocks`.`sortOrder` LIMIT 100. Bound with :locale='en_us', :contentfield_texture_sku1='JW', :contentfield_color_sku1='JW', :matrixblocksfieldId1='15')
  </code></pre>
  
  <p>The key here is the fact that my typeId isn't being applied, and this part:</p>
  
  <pre><code>(content.field_texture_sku=:contentfield_texture_sku1)) AND (content.field_color_sku=:contentfield_color_sku1))
  </code></pre>
  
  <p>I would like to query for a match independent of what type it is, as the blocks can be either or. Is there a way I can turn that into a OR query?</p>
  
  <p><a href="https://i.sstatic.net/mXDm6.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/mXDm6.png" alt="Columns"></a></p>
  
Tags: <plugin-development><matrix><elementcriteriamodel>
Title: Querying for an exact match on a Matrix block field with multiple types
ThreadText: # Querying for an exact match on a Matrix block field with multiple types
  
  (Asked by: username_0 on 2016-03-25)
  
  I'm trying to query against a specific field value in a Matrix field with multiple block types, and I've tried multiple approaches with no success. It either returns 0 results, or all blocks regardless of type.
  
  The use case is that Snipcart is doing a callback with the ordered items and their skus. I got the different product variants in a Matrix fields, and every variant has its own sku. The field have two block types. I want to find the correct product variant and reduce the available stock.
  
  The simplest approach is this:
  
  ```php
  $criteria      = craft()->elements->getCriteria(ElementType::MatrixBlock);
  $criteria->sku = 'JW';
  
  ```
  
  I figured out that it won't join the content table if you don't specify a fieldId, and you also need a typeId.
  
  ```php
  $criteria      = craft()->elements->getCriteria(ElementType::MatrixBlock);
  $criteria->fieldId = $fieldId;
  $criteria->typeId = $typeId;
  $criteria->sku = 'JW';
  
  ```
  
  What happens then is that it's seem to do the correct query, but with a AND query for the field on both block types (even though I have defined a typeId):
  
  ```
  system.db.CDbCommand.query(SELECT `elements`.`id`, `matrixblocks`.`fieldId`, `matrixblocks`.`ownerId`, `matrixblocks`.`ownerLocale`, `matrixblocks`.`typeId`, `matrixblocks`.`sortOrder`
  FROM `craft_elements` `elements`
  JOIN `craft_elements_i18n` `elements_i18n` ON elements_i18n.elementId = elements.id
  JOIN `craft_matrixcontent_colorsandtextures` `content` ON content.elementId = elements.id
  JOIN `craft_matrixblocks` `matrixblocks` ON matrixblocks.id = elements.id
  WHERE (((((((elements_i18n.locale = :locale) AND (content.locale = :locale)) AND (elements.archived = 0)) AND (elements.enabled = 1)) AND (elements_i18n.enabled = 1)) AND (content.field_texture_sku=:contentfield_texture_sku1)) AND (content.field_color_sku=:contentfield_color_sku1)) AND (matrixblocks.fieldId=:matrixblocksfieldId1)
  GROUP BY `elements`.`id`
  ORDER BY `matrixblocks`.`sortOrder` LIMIT 100. Bound with :locale='en_us', :contentfield_texture_sku1='JW', :contentfield_color_sku1='JW', :matrixblocksfieldId1='15')
  
  ```
  
  The key here is the fact that my typeId isn't being applied, and this part:
  
  ```
  (content.field_texture_sku=:contentfield_texture_sku1)) AND (content.field_color_sku=:contentfield_color_sku1))
  
  ```
  
  I would like to query for a match independent of what type it is, as the blocks can be either or. Is there a way I can turn that into a OR query?
  
  [![Columns](https://i.sstatic.net/mXDm6.png)](https://i.sstatic.net/mXDm6.png)
  
  **Tags:** plugin-development, matrix, elementcriteriamodel
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2016-03-25. Score: 5 | Accepted answer
  
  When I understand Brandon correctly in this answer [Query for blocks across Block Types using the new field parameter?](https://craftcms.stackexchange.com/a/6867/125), it's not possible to set up what you want with a criteria model.
  
  What you can do though is to add additional custom query conditions to the `dbCommand` after running the criteria model through the `buildElementsQuery` function.
  
  ```
  public function getMatrixBlocks($matrixFieldId, $fieldValue)
  {
      $criteria = craft()->elements->getCriteria(ElementType::MatrixBlock);
      $criteria->fieldId = $matrixFieldId;
  
      $dbCommand = craft()->elements->buildElementsQuery($criteria);
  
      $params = array(
          ':myFieldHandle' => $fieldValue,
      );
  
      $conditions = array('or',
          'content.field_myBlockTypeA_myFieldHandle=:myFieldHandle',
          'content.field_myBlockTypeB_myFieldHandle=:myFieldHandle',
      );
  
      $dbCommand->andWhere($conditions, $params);
  
      return $dbCommand->queryAll();
  }
  
  ```
  
  > **Comments:**
  > **username_0**: Perfect answer!  
  > **username_0**: Related to this, how do I repopulate Asset/relation fields when saving this block again?  
  > **username_0**: Fixed it thanks to this: http://craftcms.stackexchange.com/questions/11137/categories-field-is-losing-its-value-when-programmatically-updating-other-fields/11146#11146  
  
  ---
  
  