12

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.

11

You can do this in a single query using the search parameter:

{% set uncategorized = craft.entries.section('news').search('-categories:*') %}

More on searching here.

  • Cool, nice answer. – Stuart Whitehead Jul 1 '14 at 14:36
  • This is returning all of my entries, including the one with a category in news.categories – Marion Newlevant Jul 1 '14 at 19:06
  • strange, it works for me. are you on v2.1 and is your field handle "categories"? – Ben Croker Jul 1 '14 at 20:49
  • very latest 2.1.2561 and field handle categories. The category group is newsCategory – Marion Newlevant Jul 2 '14 at 3:16
  • can you rebuild the search indexes (on the settings page) and then try again? – Ben Croker Jul 2 '14 at 11:36
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() 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 %}
  • That loop is looking better and better. – Marion Newlevant Jun 30 '14 at 17:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.