<p>Start by getting the category ID(s) you want to exclude:</p>



<pre class="lang-twig prettyprint-override"><code>{% set categoryIds = craft.categories()
    .group('categories')
    .slug('category-one')
    .ids() %}
</code></pre>

<p>Then get all the entry IDs that are related to them, which should be excluded:</p>

<pre class="lang-twig prettyprint-override"><code>{% set excludeIds = craft.entries()
    .relatedTo({
        targetElement: categoryIds
    })
    .ids() %}
</code></pre>

<p>Then run your main news query, excluding those entry IDs.</p>

<pre class="lang-twig prettyprint-override"><code>{% set latestNews = craft.entries()
    .section('news')
    .id(['not']|merge(excludeIds))
    .with([
        ['image', {
            withTransforms: ['medium']
        }]
    ])
    .orderBy('postDate desc')
    .limit(4)
    .all() %}
</code></pre>

CC BY-SA 4.0
2019-01-10T20:06:18.557Z
`.id(['not']|merge(excludeIds))` 
It seems that it is only returning the entries that have category-one. I figured this would return the entries that didn't include category-one.
Michael
CC BY-SA 4.0
2019-01-10T21:37:46.983Z
@Michael it should give you all the news entries whose IDs are not in the `excludeIds` array. Support for `'not'` as a first element in the `id` param array wasn’t added until [Craft 3.0.21](https://github.com/craftcms/cms/blob/develop/CHANGELOG-v3.md#3021---2018-08-21), so make sure you’re on at least that version.
Brandon Kelly
CC BY-SA 4.0
2019-01-12T04:15:01.303Z
Do you have any insight on how the cache tag works with `.id(['not']|merge(excludeIds))`? I have a topic about it [here](https://craftcms.stackexchange.com/questions/29082/cache-busting-blog-index-vs-blog-category-has-mixed-results)
Michael
CC BY-SA 4.0
2019-01-10T18:43:36.127Z
2019-01-10T18:43:36.127Z
Brandon Kelly
<p>I've reference this <a href="https://craftcms.stackexchange.com/questions/9344/exclude-category-from-channel-entries-with-pagination">related thread</a> but haven't found a working solution that supports pagination and will exclude entries that have multiple categories.</p>

<p>The code example will not include Category One, but when an entry has Category One and Category Two it will still display because Category Two is included in the cateogries array. Is there a way to still exclude the entry even if it's second category is included?</p>

<pre><code>  {# Get all the categories you want to INCLUDE #}
  {% set categories = craft.categories({
      group: 'categories',
      slug: [
        'not category-one',
      ],
      limit: null,
    }).all() %}

  {# Get entries related to your desired categories #}
  {% set latestNews = craft.entries({
      section: 'news',
      relatedTo: categories,
      with: ([
        ['image', {
          withTransforms: ['medium']
        }]
      ]),
      orderBy: 'postDate desc',
      limit: 4
    }).all() %}
</code></pre>

<craft3><categories>
Issue Excluding Entries with Multiple Categories in Query
# Issue Excluding Entries with Multiple Categories in Query

(Asked by: username_0 on 2019-01-10)

I've reference this related thread but haven't found a working solution that supports pagination and will exclude entries that have multiple categories.
The code example will not include Category One, but when an entry has Category One and Category Two it will still display because Category Two is included in the cateogries array. Is there a way to still exclude the entry even if it's second category is included?
  {# Get all the categories you want to INCLUDE #}
  {% set categories = craft.categories({
      group: 'categories',
      slug: [
        'not category-one',
      ],
      limit: null,
    }).all() %}

  {# Get entries related to your desired categories #}
  {% set latestNews = craft.entries({
      section: 'news',
      relatedTo: categories,
      with: ([
        ['image', {
          withTransforms: ['medium']
        }]
      ]),
      orderBy: 'postDate desc',
      limit: 4
    }).all() %}

**Tags:** craft3, categories


---

## 1 answers

### Answer by username_1 on 2019-01-10. Score: 3 | Accepted answer

Start by getting the category ID(s) you want to exclude:
{% set categoryIds = craft.categories()
    .group('categories')
    .slug('category-one')
    .ids() %}

Then get all the entry IDs that are related to them, which should be excluded:
{% set excludeIds = craft.entries()
    .relatedTo({
        targetElement: categoryIds
    })
    .ids() %}

Then run your main news query, excluding those entry IDs.
{% set latestNews = craft.entries()
    .section('news')
    .id(['not']|merge(excludeIds))
    .with([
        ['image', {
            withTransforms: ['medium']
        }]
    ])
    .orderBy('postDate desc')
    .limit(4)
    .all() %}

> **Comments:**
> **username_0**: `.id(['not']|merge(excludeIds))`  It seems that it is only returning the entries that have category-one. I figured this would return the entries that didn't include category-one.  
> **username_1**: @username_0 it should give you all the news entries whose IDs are not in the `excludeIds` array. Support for `'not'` as a first element in the `id` param array wasn’t added until [Craft 3.0.21](https://github.com/craftcms/cms/blob/develop/CHANGELOG-v3.md#3021---2018-08-21), so make sure you’re on at least that version.  
> **username_0**: Do you have any insight on how the cache tag works with `.id(['not']|merge(excludeIds))`? I have a topic about it [here](https://craftcms.stackexchange.com/questions/29082/cache-busting-blog-index-vs-blog-category-has-mixed-results)  

---

