# Meaning of regexp query complement operator

**URL:** <https://discuss.elastic.co/t/meaning-of-regexp-query-complement-operator/79224>\
**Category:** Elasticsearch\
**Created:** [March 20, 2017, 9:44am UTC](https://discuss.elastic.co/t/meaning-of-regexp-query-complement-operator/79224 "2017-03-20T09:44:40Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Igor\_Berman](https://avatars.discourse-cdn.com/v4/letter/i/977dab/32.png) [@Igor\_Berman](https://discuss.elastic.co/u/Igor_Berman)\
**Post date:** [March 20, 2017, 9:44am UTC](https://discuss.elastic.co/t/meaning-of-regexp-query-complement-operator/79224/1 "2017-03-20T09:44:40Z")

</div>

Hi All,  
if you can help me with understanding what is complement in regexp queries really is by example  
I've read documentation, however it's still not clear for me

e.g. I have following regexp query that tries to select only Android 4.0 user agents, the problem is that Windows Phone 8.1 has same Android 4.0 part inside, so I've created following:

```auto
    "regexp" : {
      "userAgent" : {
        "value" : "~(.*Windows Phone)(.*)Android 4\\.0(.*)",
        "flags": "COMPLEMENT"
      }
    }

```

the problem is that user agent values like  
`Mozilla/5.0 (Mobile; Windows Phone 8.1; Android 4.0; ARM; Trident/7.0; Touch; rv:11.0; IEMobile/11.0; Microsoft; Lumia 640 Dual SIM) like iPhone OS 7_0_3 Mac OS X AppleWebKit/537 (KHTML, like Gecko) Mobile Safari/537`

do match the regexp, while I've tried to "exclude" Windows Phone" from the match

What I'm missing? How to think about complement ~ in lucene regexps?  
Isn't my query tells something like:  
every value that doesn't have Windows Phone at the beginning, then has anything else, then "Android 4.0" and then once again anything else

Update:  
I've managed to get what I want with Intersection, however in manual it's advised to rethink approach and not to use it

```auto
    "regexp" : {
      "userAgent" : {
        "value" : "~(.*Windows Phone.*)&.*Android 4\\.0.*",
        "flags": "COMPLEMENT|INTERSECTION"
      }
    }

```

Thanks in advance

---

<div class="post-metadata">

**Author:** ![Clinton\_Gormley](https://avatars.discourse-cdn.com/v4/letter/c/50afbb/32.png) [@Clinton\_Gormley](https://discuss.elastic.co/u/Clinton_Gormley)\
**Post date:** [March 24, 2017, 8:21am UTC](https://discuss.elastic.co/t/meaning-of-regexp-query-complement-operator/79224/2 "2017-03-24T08:21:33Z")

</div>

I think what you've done with Intersection looks right - I can't think of any other way to achieve what you want.

General advice though: doing this with a regexp query at query time is EXPENSIVE. Much better to tag your documents appropriately at index time (eg using the [ingest-user-agent](https://www.elastic.co/guide/en/elasticsearch/plugins/current/ingest-user-agent.html) plugin)

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [April 21, 2017, 8:22am UTC](https://discuss.elastic.co/t/meaning-of-regexp-query-complement-operator/79224/3 "2017-04-21T08:22:30Z")

</div>

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.
