Page MenuHomePhabricator

"NOT" filter for all applicable lines in a Query
Closed, WontfixPublic


It would be very usable if most query filters everywhere would have an option to select whether I want results that match the field or that do NOT match the field.

I am sure this would have a massive amount of use cases.

Related Objects

Restricted Pholio Mock

Event Timeline

allan.laal raised the priority of this task from to Needs Triage.
allan.laal updated the task description. (Show Details)
allan.laal added a project: Projects.
allan.laal added a subscriber: allan.laal.

nice ticket number :D

What's your use case here? Why do you want to see this list of projects?

I want to see if some other member has created a project to check if I should join it (being the all-knowing Admin), or whether its just spam/testing.

allan.laal renamed this task from Project page query: "NOT members" filter in addition to "Members" filter to "NOT" filter for every line in a Query.Feb 17 2014, 4:36 PM
allan.laal updated the task description. (Show Details)


epriestley triaged this task as Wishlist priority.Feb 17 2014, 4:44 PM

It is vaguely possible we might some day let you write meta-queries that would perform set operations on other queries. In effect, this would let you NOT (or OR, or AND) any set of conditions with any other set.

However, this would be complex to implement and complex to write a UI for. We've also seen very little interest in anything this would provide.

This also doesn't sound like a very good solution to the use case. Here are two examples where the use case is not well served by the suggested feature:

  • Someone creates a spam project and adds you as a member.
  • Or, over time, your install has 100+ projects which you are not a member of, and scanning them visually to find new ones becomes hard.

A better approach would probably be an "order by: date created" filter. You could examine recently created projects until you hit something you recognized, and this will scale to a large number of projects.

allan.laal renamed this task from "NOT" filter for every line in a Query to "NOT" filter for all applicable lines in a Query.Feb 17 2014, 4:45 PM

the "order by: date created" filter would satisfy the initial use case, however I kinda hijacked this task and Pivoted it to be more general

Do you have other use cases for the more general version of this?

I have found myself wanting to apply one or all of the filters below to a Maniphest task search query:
NOT assigned to
NOT authored by
NOT subscribed by (to find if I should CC someone, applies to small projects, usually a part of a bigger query)
Title does NOT contain
Title contains (right now its searching in title and text, which gives too much false positives)

priority NOT xyz
priority NOT xyz, zyy, xxx
status NOT xxx

Another use case:

I just wanted to search for Maniphest tasks where 1..N custom fields are EMPTY
I need to find closed tasks assigned to me that have these fields empty to enter follow-up details, that my own system polls via Conduit for making reports and statistics

epriestley claimed this task.

We've seen very few requests for this kind of thing and don't plan to implement it any time in the near future.

This is something that is needed every day, e.g. find tickets which are not yet assigned..

You can find tasks with no owner by searching for "No Owner", like this:

Screen Shot 2017-06-27 at 4.47.25 AM.png (192×780 px, 20 KB)

You can click the icon (at the far right side of the input), then click "Reference: Advanced Functions" for complete documentation on available functions.

Since this is already possible, it isn't a good use case to motivate universal "NOT" filters. They also could not solve this problem on their own, since there is no way to say "Any Owner" without typeahead functions (with typeahead functions, use the "Any Owner" function).

@epriestley As perhaps an example of another use case, in my workplace we needed, amongst others, the following lists of Maniphest tasks:

  1. assigned to the viewer, regardless of the author,
  2. authored by the viewer, without self-assigned,
  3. subscribed by the viewer, without (1) and (2).

(1) is obviously trivial (there's already a built-in query), but the other two seemed to require custom "NOT" filtering. Of course, (2) can be solved to an extent by using "Group by assigned", but it's not very convenient. Because I tend to self-assign most of the tasks that I create, the ones that I have assigned to other people quickly get visually overwhelmed by the large group of "Assigned to kerberizer" (not to mention that with my username this huge group tends to get in the middle of the list).

Now, this doesn't necessarily need a generic "NOT" filter. In the end, I went with sort of a !viewer() typeahead in a new PhabricatorNotViewerDatasource class. The key difference from PhabricatorViewerDatasource is this:

protected function evaluateFunction($function, array $argv_list) {
  $viewer_phid = $this->getViewer()->getPHID();

  $people = id(new PhabricatorPeopleQuery())

  $results = array();
  foreach ($people as $person) {
    $phid = $person->getPHID();
    if ($phid != $viewer_phid) {
      $results[$phid] = $phid;

  return array_values($results);

Disclaimer: for me this was largely a Changing Stuff and Seeing What Happens thing, not to mention that I have very little experience with PHP in particular and relatively little with programming in general, so this may not be a/the correct solution or at least it may have potential problems—like it doesn't check if the user query returns anything at all, though it should perhaps at least return us—but it seems to do the job, so I actually put it into production in our Phabricator instance.

I thought I'd share this, as, unlike the generic "NOT" filter, such "inverse" viewer() typeahead may be a solution to a probably frequent use case, without being too involving to implement. Of course, especially from UI side, there are possible complications too, like "Current Viewer" and "Not Current Viewer" not being mutually exclusive. Selecting both, of course, would simply be the equivalent of "Any" or just leaving the field empty, but some people might still get confused.

Screenshot from 2020-02-26 20-58-28.png (440×835 px, 46 KB)

If you think it might be worth to open a task for this, please let me know, and I'll do it.