# New search operator "not" for tags only

**URL:** https://meta.discourse.org/t/new-search-operator-not-for-tags-only/52087
**Category:** Feature
**Tags:** search
**Created:** [27 oktober 2016 om 10:27 UTC](https://meta.discourse.org/t/new-search-operator-not-for-tags-only/52087 "2016-10-27T10:27:15Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![jomaxro](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/jomaxro/32/126216_2.png) [@jomaxro](https://meta.discourse.org/u/jomaxro)
#### Post date: [27 oktober 2016 om 10:27 UTC](https://meta.discourse.org/t/new-search-operator-not-for-tags-only/52087/1 "2016-10-27T10:27:15Z")

</div>

Over at Stonehearth we’ve started to have the want to search for topics that _don’t_ have a certain tag on them, or that aren’t by a certain user. To the best of my understanding, this isn’t currently possible. As such, we’d like to request a negation operator for search, like Google support `-`.

---

<div class="post-metadata">

### Author: ![jomaxro](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/jomaxro/32/126216_2.png) [@jomaxro](https://meta.discourse.org/u/jomaxro)
#### Post date: [14 november 2016 om 18:07 UTC](https://meta.discourse.org/t/new-search-operator-not-for-tags-only/52087/2 "2016-11-14T18:07:36Z")

</div>

So this just came up naturally from another user at Stonehearth:

> **[Better search, filters](https://discourse.stonehearth.net/t/better-search-filters/26654)**
>
> Is there a way similar to google’s search to use special filters? I’m looking specific for exclusion filters, but a list of all filters (if any) would be good. A simple search here for something like frog will show a lot of posts where the user...

Seems he was trying to search for “frog”, but we have a very active user named “froggy” so he had a hard time searching for posts that had frog but weren’t mentions.

---

<div class="post-metadata">

### Author: ![ccstone](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/ccstone/32/140215_2.png) [@ccstone](https://meta.discourse.org/u/ccstone)
#### Post date: [11 mei 2017 om 02:32 UTC](https://meta.discourse.org/t/new-search-operator-not-for-tags-only/52087/3 "2017-05-11T02:32:47Z")

</div>

I’m amazed this topic didn’t get any more traction…

As the Keyboard Maestro forum gains more and more threads it’s becoming increasingly difficult to find things efficiently.

A negation operator would be helpful.

-Chris

---

<div class="post-metadata">

### Author: ![codinghorror](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/codinghorror/32/110067_2.png) [@codinghorror](https://meta.discourse.org/u/codinghorror)
#### Post date: [11 mei 2017 om 04:37 UTC](https://meta.discourse.org/t/new-search-operator-not-for-tags-only/52087/4 "2017-05-11T04:37:40Z")

</div>

You can use negation in Google searches with the site: operator, so try that. Visit the 404 page (type any random gobbledygook as a URL past the domain name) to get a pre filled google search form.

---

<div class="post-metadata">

### Author: ![sam](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/sam/32/102149_2.png) [@sam](https://meta.discourse.org/u/sam)
#### Post date: [11 mei 2017 om 12:30 UTC](https://meta.discourse.org/t/new-search-operator-not-for-tags-only/52087/5 "2017-05-11T12:30:31Z")

</div>

It is actually a pretty straight forward change (add support for `-test`) which would be only about 10-20 lines of code including tests (as long as its not in the advanced page with a fancy UI). Going to put a #pr-welcome on this, I don’t think it would do any harm.

---

<div class="post-metadata">

### Author: ![david](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/david/32/157490_2.png) [@david](https://meta.discourse.org/u/david)
#### Post date: [11 mei 2017 om 14:57 UTC](https://meta.discourse.org/t/new-search-operator-not-for-tags-only/52087/7 "2017-05-11T14:57:12Z")

</div>

Using google wont work for login-only forums, or secure categories

---

<div class="post-metadata">

### Author: ![codinghorror](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/codinghorror/32/110067_2.png) [@codinghorror](https://meta.discourse.org/u/codinghorror)
#### Post date: [11 mei 2017 om 15:29 UTC](https://meta.discourse.org/t/new-search-operator-not-for-tags-only/52087/8 "2017-05-11T15:29:50Z")

</div>

That does not apply to the forum in question at [https://forum.keyboardmaestro.com](https://forum.keyboardmaestro.com)

So they can easily kick off a search with negation by going to [https://forum.keyboardmaestro.com/nf](https://forum.keyboardmaestro.com/nf)

---

<div class="post-metadata">

### Author: ![kasiabulat](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/kasiabulat/32/86402_2.png) [@kasiabulat](https://meta.discourse.org/u/kasiabulat)
#### Post date: [17 december 2017 om 16:16 UTC](https://meta.discourse.org/t/new-search-operator-not-for-tags-only/52087/9 "2017-12-17T16:16:58Z")

</div>

Hi, I am quite new to the project, but I can try to add this feature.

---

<div class="post-metadata">

### Author: ![erlend\_sh](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/erlend_sh/32/119475_2.png) [@erlend\_sh](https://meta.discourse.org/u/erlend_sh)
#### Post date: [19 december 2017 om 11:31 UTC](https://meta.discourse.org/t/new-search-operator-not-for-tags-only/52087/10 "2017-12-19T11:31:09Z")

</div>

That’s great @kasiabulat. Do you have a good idea of where to start with this or do you need some guidance?

---

<div class="post-metadata">

### Author: ![kasiabulat](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/kasiabulat/32/86402_2.png) [@kasiabulat](https://meta.discourse.org/u/kasiabulat)
#### Post date: [21 december 2017 om 18:45 UTC](https://meta.discourse.org/t/new-search-operator-not-for-tags-only/52087/11 "2017-12-21T18:45:12Z")

</div>

Thank you @erlend_sh for offering help! I think that the best and easiest way to do it would be to perform two searches:

- Firstly, search for the term before the not part
- Then, in results, search for the ones containing the unwanted phrase and filter them out

Is [discourse/app/assets/javascripts/discourse/widgets/search-menu.js.es6 at 87c334c06365f273f39038d91ab92488c4757041 · discourse/discourse · GitHub](https://github.com/discourse/discourse/blob/87c334c06365f273f39038d91ab92488c4757041/app/assets/javascripts/discourse/widgets/search-menu.js.es6) the correct file to make changes in?

---

<div class="post-metadata">

### Author: ![cpradio](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/cpradio/32/4970_2.png) [@cpradio](https://meta.discourse.org/u/cpradio)
#### Post date: [21 december 2017 om 21:06 UTC](https://meta.discourse.org/t/new-search-operator-not-for-tags-only/52087/12 "2017-12-21T21:06:50Z")

</div>

The larger part of your changes will be in

> <https://github.com/discourse/discourse/blob/main/lib/search.rb>

---

<div class="post-metadata">

### Author: ![kasiabulat](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/kasiabulat/32/86402_2.png) [@kasiabulat](https://meta.discourse.org/u/kasiabulat)
#### Post date: [3 januari 2018 om 22:04 UTC](https://meta.discourse.org/t/new-search-operator-not-for-tags-only/52087/13 "2018-01-03T22:04:25Z")

</div>

Thank you @cpradio for help with finding the correct file.

For the beginning, I added a simple version of search operator “not” (~) for tags. Currently it has the highest precedence and I implemented it as I described above. But I am wondering if it would be better for ‘+’ or ‘,’ to have higher precedence? And should it be possible to combine all operators? What way would be the best for users to construct their queries?

Pull request: [Add search not operator by kasiabulat · Pull Request #5467 · discourse/discourse · GitHub](https://github.com/discourse/discourse/pull/5467)

---

<div class="post-metadata">

### Author: ![kasiabulat](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/kasiabulat/32/86402_2.png) [@kasiabulat](https://meta.discourse.org/u/kasiabulat)
#### Post date: [15 januari 2018 om 21:38 UTC](https://meta.discourse.org/t/new-search-operator-not-for-tags-only/52087/14 "2018-01-15T21:38:21Z")

</div>

I added some tests and comments about the performance issue to my pull request.

---

<div class="post-metadata">

### Author: ![tgxworld](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/tgxworld/32/106117_2.png) [@tgxworld](https://meta.discourse.org/u/tgxworld)
#### Post date: [22 februari 2018 om 10:06 UTC](https://meta.discourse.org/t/new-search-operator-not-for-tags-only/52087/15 "2018-02-22T10:06:22Z")

</div>

I’m not sure about using `~` to represent NOT since it is usually used when matching against regular expressions. In Ruby, we use `=~ /^some_regexp_pattern/` and it is similar in Postgres as well.

 ![Screenshot%20from%202018-02-22%2018-03-34](https://global.discourse-cdn.com/meta/original/3X/a/7/a75a795c5fa9a163db9d5254baced37e0f363913.png)

---

<div class="post-metadata">

### Author: ![gerhard](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/gerhard/32/119479_2.png) [@gerhard](https://meta.discourse.org/u/gerhard)
#### Post date: [22 februari 2018 om 10:29 UTC](https://meta.discourse.org/t/new-search-operator-not-for-tags-only/52087/16 "2018-02-22T10:29:51Z")

</div>

I agree that using `~` as operator probably isn’t a good idea.  
@kasiabulat Why did you choose `~` instead of `-` as “not” operator?

I’d prefer `tags:eggs-lunch+sandwiches` or `tags:eggs!lunch+sandwiches` to `tags:eggs~lunch+sandwiches`

---

<div class="post-metadata">

### Author: ![tgxworld](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/tgxworld/32/106117_2.png) [@tgxworld](https://meta.discourse.org/u/tgxworld)
#### Post date: [22 februari 2018 om 11:20 UTC](https://meta.discourse.org/t/new-search-operator-not-for-tags-only/52087/17 "2018-02-22T11:20:11Z")

</div>

> [@gerhard](#):
>
> instead of - as “not” operator?

Ah ha this was probably not chosen because `-` are allowed in tags.

---

<div class="post-metadata">

### Author: ![gerhard](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/gerhard/32/119479_2.png) [@gerhard](https://meta.discourse.org/u/gerhard)
#### Post date: [22 februari 2018 om 11:25 UTC](https://meta.discourse.org/t/new-search-operator-not-for-tags-only/52087/18 "2018-02-22T11:25:55Z")

</div>

Using quotes would help: `tags:"boiled-eggs"-lunch+sandwiches`

---

<div class="post-metadata">

### Author: ![featheredtoast](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/featheredtoast/32/116994_2.png) [@featheredtoast](https://meta.discourse.org/u/featheredtoast)
#### Post date: [22 februari 2018 om 16:46 UTC](https://meta.discourse.org/t/new-search-operator-not-for-tags-only/52087/19 "2018-02-22T16:46:06Z")

</div>

Probably not the best idea to require quotes as a naive search on `tags:boiled-eggs` would no longer do what you’d expect. Is there any conflict with `!`? That would be my preference here.

---

<div class="post-metadata">

### Author: ![kasiabulat](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/kasiabulat/32/86402_2.png) [@kasiabulat](https://meta.discourse.org/u/kasiabulat)
#### Post date: [12 maart 2018 om 07:08 UTC](https://meta.discourse.org/t/new-search-operator-not-for-tags-only/52087/20 "2018-03-12T07:08:53Z")

</div>

Should I change it into “!”, then?

---

<div class="post-metadata">

### Author: ![kasiabulat](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/kasiabulat/32/86402_2.png) [@kasiabulat](https://meta.discourse.org/u/kasiabulat)
#### Post date: [12 maart 2018 om 08:11 UTC](https://meta.discourse.org/t/new-search-operator-not-for-tags-only/52087/21 "2018-03-12T08:11:55Z")

</div>

I added a commit with the proper change: [Add search not operator by kasiabulat · Pull Request #5467 · discourse/discourse · GitHub](https://github.com/discourse/discourse/pull/5467/commits/d01f064cf5c0a167876c1f9bd4730a3af951795d)

[Volgende pagina](https://meta.discourse.org/t/new-search-operator-not-for-tags-only/52087.md?page=2)
