I think a useful filter operator would be "Is not equal to OR is empty", because it is quite hard to achieve that currently.

Because:

field != 'value' doesn't get results that match field IS NULL you can get unexpected results when using the "Is not equal" operators with data that is not required.

For example if I said I wanted nodes where the "name" field is not equal to "Reuben" I would likely expect a node with no "name" at all to be included because no name is not the same as "Reuben".

You could use views OR functionality to make it happen, however that won't work out very well for exposed filters.

So if we have an option to say (field != 'value' OR field IS NULL) I think that would be a useful addition.

Comments

swelljoe’s picture

Issue summary: View changes

This seems like it should be the default behavior for the "does not equal" filter. I just spent a couple of hours trying to figure out why this wasn't working as expected; it really is baffling that does not equal "something" would ever match on a blank field.

At the very least, this unintuitive behavior should be documented in the description of the various "does not equal" filters (the problem also applies to "does not contain", "does not start with", "does not end with", etc.).

alberto56’s picture

Project: Views (for Drupal 7) » Drupal core
Version: 7.x-3.x-dev » 10.1.x-dev
Component: Miscellaneous » ajax system

In my tests this still seems to be an issue: if I have two nodes, one whose field_test is abc and one whose field_test is not set, and I filter by field_test NOT EQUAL TO "abc", I am not getting the node where field_test is not set.

alberto56’s picture

Component: ajax system » views.module
alberto56’s picture

Here is a workaround that works for me.

Let's say you have two nodes,

* node 1 contains field_test = "abc"
* node 2 contains field_test is EMPTY

And you are constructing a view with where you want to show

* both nodes by default
* if you set an exposed filter test=abc, you want only node 1
* if you set an exposed filter not_test=abc, you want only node 2

Here is a set of filters which work:

* Filter 1: start by creating an exposed filter for field_test call test with the operator "Contains"
* Filter 2: create another exposed filter for field_test called not_test with the operator "Does not contain". **The trick here is that this exposed filter's default value cannot be empty: it needs to be something which does not exist on your site**, so I put something like "Use this filter to filter your content by nodes which do not contain a word" in the value. It does not matter what you put in the field, it cannot be empty**
* Filter 3: now create another filter, not exposed, on field_test, with the operator "is empty (NULL)"
* now in the views overview, next to the filter criteria in the little "Add" button, click on the arrow and select "And/Or Rearrange"
* Create a new filter, and select "AND" between the two filter groups
* Select "OR" within your new, second, filter group. (Note that because of #3346391: Views filter groups: selecting OR works as expected, but displays AND, which can be conflusing to site builders you might still see the word AND even when selecting OR, but this will still work as expected.)
* Drag filters 2 and 3 into the new OR group.

Save your view.

Now, assuming you have a rest you will be able to filter your view:

http://0.0.0.0/path_to_my_view?not_test=abc will show node 2
http://0.0.0.0/path_to_my_view?test=abc will show node 1
http://0.0.0.0/path_to_my_view will show nodes 1 and 2

This workaround is unwieldy, so it would still be nice to have a "Does not contain, or is empty" operator.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Lendude’s picture

See #2769407: Views UI should offer a 'Treat NULL values as FALSE' on boolean field filtering to expose the already existing code path for handling this for the boolean version of this request.

See https://www.drupal.org/project/field_defaults for what I feel is the correct solution for this that works for all field types and takes the actual default value of a field into account