Answers.Body: <p>If you're wanting to avoid a loop, I think the best solution here would be to find the entries which <em>do</em> have a category set and work backwards using the <a href="http://buildwithcraft.com/docs/templating/filters#without" rel="nofollow"><code>|without()</code></a> filter. I can't see this being possible in only one query.</p>
  
  <pre><code>{# First, get your categories #}
  {% set categories = craft.categories.group('optionalGroup').ids() %}
  
  {# Find all news entries which have a category set #}
  {% set newsWithCategories = craft.entries.section('news').relatedTo({targetElement: categories}).ids() %}
  
  {# Now find news without categories #}
  {% set newsWithoutCategories = craft.entries.section('news').ids()|without(newsWithCategories) %}
  
  {# Finally retrieve the EntryModels #}
  {% set newsEntries = craft.entries.section('news').id(newsWithoutCategories).find() %}
  </code></pre>
  
  <p>As you can see, there are quite a few calls to the DB being made here. This little algorithm would probably be more efficient with a loop.</p>
  
  <pre><code>{% set newsEntries = [] %}
  {% for news in craft.entries.section('news').find() %}
      {% if news.categories is empty %}
          {% set newsEntries = newsEntries|merge([news]) %}
      {% endif %}
  {% endfor %}
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-06-30T17:25:12.377Z
Answers.Text: That loop is looking better and better.
Answers.UserDisplayName: Marion Newlevant
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-06-30T11:14:23.630Z
Answers.LastActivityDate: 2014-06-30T11:14:23.630Z
Answers.UserDisplayName: Stuart Whitehead
Answers.Body: <p>You can do this in a single query using the search parameter:</p>
  
  <pre class="lang-twig prettyprint-override"><code>{% set uncategorized = craft.entries.section('news').search('-categories:*') %}
  </code></pre>
  
  <p>More on <a href="http://buildwithcraft.com/docs/searching">searching here</a>.</p>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-07-01T14:36:30.833Z
Answers.Text: Cool, nice answer.
Answers.UserDisplayName: Stuart Whitehead
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-07-01T19:06:41.877Z
Answers.Text: This is returning all of my entries, including the one with a category in news.categories
Answers.UserDisplayName: Marion Newlevant
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-07-01T20:49:27.500Z
Answers.Text: strange, it works for me. are you on v2.1 and is your field handle "categories"?
Answers.UserDisplayName: Ben Croker
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-07-02T03:16:28.713Z
Answers.Text: very latest 2.1.2561 and field handle categories. The category group is newsCategory
Answers.UserDisplayName: Marion Newlevant
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-07-02T11:36:46.923Z
Answers.Text: can you rebuild the search indexes (on the settings page) and then try again?
Answers.UserDisplayName: Ben Croker
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-07-03T05:30:39.743Z
Answers.Text: That fixed it! And also the parallel problem I was having with untagged entries. Thank you so much!
Answers.UserDisplayName: Marion Newlevant
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-07-03T09:06:11.287Z
Answers.Text: great, i've reported a bug to P&T which should address this issue in future
Answers.UserDisplayName: Ben Croker
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-07-08T16:19:49.953Z
Answers.Text: fixed in this update http://buildwithcraft.com/updates#build2563
Answers.UserDisplayName: Ben Croker
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-07-01T11:37:23.280Z
Answers.LastActivityDate: 2014-07-01T11:37:23.280Z
Answers.UserDisplayName: Ben Croker
Body: <p>I have a field <code>categories</code> in a channel <code>news</code>, and I want to find all the entries in <code>news</code> that don't have a category set. I know I could loop over the entries and find them that way, but I'm hoping to do it with a query. I tried</p>
  
  <pre><code>{% set uncategorized = craft.entries.section('news').categories(':empty:') %}
  </code></pre>
  
  <p>But it returned none.</p>
  
Tags: <categories><elementcriteriamodel>
Title: How to find entries with no category
ThreadText: # How to find entries with no category
  
  (Asked by: username_0 on 2014-06-30)
  
  I have a field `categories` in a channel `news`, and I want to find all the entries in `news` that don't have a category set. I know I could loop over the entries and find them that way, but I'm hoping to do it with a query. I tried
  
  ```
  {% set uncategorized = craft.entries.section('news').categories(':empty:') %}
  
  ```
  
  But it returned none.
  
  **Tags:** categories, elementcriteriamodel
  
  
  ---
  
  ## 2 answers
  
  ### Answer by username_2 on 2014-07-01. Score: 11 | Accepted answer
  
  You can do this in a single query using the search parameter:
  
  ```twig
  {% set uncategorized = craft.entries.section('news').search('-categories:*') %}
  
  ```
  
  More on [searching here](http://buildwithcraft.com/docs/searching).
  
  > **Comments:**
  > **username_1**: Cool, nice answer.  
  > **username_0**: This is returning all of my entries, including the one with a category in news.categories  
  > **username_2**: strange, it works for me. are you on v2.1 and is your field handle "categories"?  
  > **username_0**: very latest 2.1.2561 and field handle categories. The category group is newsCategory  
  > **username_2**: can you rebuild the search indexes (on the settings page) and then try again?  
  > **username_0**: That fixed it! And also the parallel problem I was having with untagged entries. Thank you so much!  
  > **username_2**: great, i've reported a bug to P&T which should address this issue in future  
  > **username_2**: fixed in this update http://buildwithcraft.com/updates#build2563  
  
  ---
  
  ### Answer by username_1 on 2014-06-30. Score: 4
  
  If you're wanting to avoid a loop, I think the best solution here would be to find the entries which *do* have a category set and work backwards using the [`|without()`](http://buildwithcraft.com/docs/templating/filters#without) filter. I can't see this being possible in only one query.
  
  ```
  {# First, get your categories #}
  {% set categories = craft.categories.group('optionalGroup').ids() %}
  
  {# Find all news entries which have a category set #}
  {% set newsWithCategories = craft.entries.section('news').relatedTo({targetElement: categories}).ids() %}
  
  {# Now find news without categories #}
  {% set newsWithoutCategories = craft.entries.section('news').ids()|without(newsWithCategories) %}
  
  {# Finally retrieve the EntryModels #}
  {% set newsEntries = craft.entries.section('news').id(newsWithoutCategories).find() %}
  
  ```
  
  As you can see, there are quite a few calls to the DB being made here. This little algorithm would probably be more efficient with a loop.
  
  ```
  {% set newsEntries = [] %}
  {% for news in craft.entries.section('news').find() %}
      {% if news.categories is empty %}
          {% set newsEntries = newsEntries|merge([news]) %}
      {% endif %}
  {% endfor %}
  
  ```
  
  > **Comments:**
  > **username_0**: That loop is looking better and better.  
  
  ---
  
  