# Queries on "ip\_range" type (missing documentation)

**URL:** https://discuss.elastic.co/t/queries-on-ip-range-type-missing-documentation/246445
**Category:** Elasticsearch
**Created:** [August 26, 2020, 11:33am UTC](https://discuss.elastic.co/t/queries-on-ip-range-type-missing-documentation/246445 "2020-08-26T11:33:30Z")
**Posts on this page:** 9
**Page:** 1

<div class="post-metadata">

### Author: ![YvorL](https://avatars.discourse-cdn.com/v4/letter/y/9fc348/32.png) [@YvorL](https://discuss.elastic.co/u/YvorL)
#### Post date: [August 26, 2020, 11:33am UTC](https://discuss.elastic.co/t/queries-on-ip-range-type-missing-documentation/246445/1 "2020-08-26T11:33:31Z")

</div>

Hi,

Unfortunately, I couldn't find any pointers in the [documentation](https://www.elastic.co/guide/en/elasticsearch/reference/current/range.html#ip-range). I'd like to have some IP ranges saved and be able to:

1. Perform a query for an IP address.
2. Perform a query for a CIDR range.

I got #1 working with [query string query](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html) (e.g., `{"query":{"query_string":{"query":"iprangefield:172.16.0.0"}}}`) but it doesn't look elegant and I'm wondering if there's a better way to do this. Something like the term query?

The other issue I have is that I don't know how to "match" a document. I need a way to see if there's already a document with the **same** field. Also, a way to check if a subnet is part of an existing document (larger prefix).

Thank you!

---

<div class="post-metadata">

### Author: ![YvorL](https://avatars.discourse-cdn.com/v4/letter/y/9fc348/32.png) [@YvorL](https://discuss.elastic.co/u/YvorL)
#### Post date: [September 1, 2020, 11:27am UTC](https://discuss.elastic.co/t/queries-on-ip-range-type-missing-documentation/246445/2 "2020-09-01T11:27:42Z")

</div>

Bump

---

<div class="post-metadata">

### Author: ![whatgeorgemade](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/whatgeorgemade/32/103246_2.png) [@whatgeorgemade](https://discuss.elastic.co/u/whatgeorgemade)
#### Post date: [September 2, 2020, 9:00am UTC](https://discuss.elastic.co/t/queries-on-ip-range-type-missing-documentation/246445/3 "2020-09-02T09:00:28Z")

</div>

An `ip_range` field can be treated in the same way as any other `range` type field. See the docs [here](https://www.elastic.co/guide/en/elasticsearch/reference/7.9/query-dsl-range-query.html). The field value will be a network.

One thing to remember with `ip_range` fields is that if a document contains the range `0.0.0.0/0`, it will match all queries.

You can find documents where the `ip_range` field contains a certain IP address using the `match` query. For example:

```auto
{
  "query": {
    "iprangefield": {
      "addr": "192.168.1.17"
    }
  }
}

```

You can also use a `range` query to see if document contains another network. For example:

```auto
{
  "query": {
    "range": {
      "iprangefield": {
        "from": "192.168.1.10",
        "to": "192.168.1.15"
      }
    }
  }
}

```

---

<div class="post-metadata">

### Author: ![YvorL](https://avatars.discourse-cdn.com/v4/letter/y/9fc348/32.png) [@YvorL](https://discuss.elastic.co/u/YvorL)
#### Post date: [September 2, 2020, 11:38am UTC](https://discuss.elastic.co/t/queries-on-ip-range-type-missing-documentation/246445/4 "2020-09-02T11:38:35Z")

</div>

@whatgeorgemade  
Thanks! I got the match part working:

```
{
  "query": {
    "match": {
       "iprangefield": "172.16.0.0"
    }
  }
}

```

I got that one messed up somehow before...

Though, I still don't know how to match an exact range to avoid duplication. Do you have any idea? I want to avoid translating CIDR to two IP addresses get the result set, then post-process it to see if I get a match.

---

<div class="post-metadata">

### Author: ![whatgeorgemade](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/whatgeorgemade/32/103246_2.png) [@whatgeorgemade](https://discuss.elastic.co/u/whatgeorgemade)
#### Post date: [September 3, 2020, 9:05am UTC](https://discuss.elastic.co/t/queries-on-ip-range-type-missing-documentation/246445/5 "2020-09-03T09:05:35Z")

</div>

Matching the exact range is a bit more involved as range fields aren't meant for this sort of query.

One strategy would be to change your mapping and add a `keyword` [multi-field](https://www.elastic.co/guide/en/elasticsearch/reference/7.9/multi-fields.html) that holds the original network address and mask. You can then do an exact match against that using a `match` query.

For example:

```auto
PUT testiprangefield
{
  "settings": {
    "number_of_replicas": 0
  },
  "mappings": {
    "properties": {
      "iprangefield": {
        "type": "ip_range",
        "fields": {
          "raw": {
            "type": "keyword"
          }
        }
      }
    }
  }
}

```

You can add documents in the usual way:

```auto
PUT testiprangefield/_doc/1
{
  "iprangefield": "192.168.1.1/28"
}

```

Then search against the `raw` multi-field.

```auto
GET testiprangefield/_search
{
  "query": {
    "match": {
      "iprangefield.raw": "192.168.1.1/28"
    }
  }
}

```

---

<div class="post-metadata">

### Author: ![YvorL](https://avatars.discourse-cdn.com/v4/letter/y/9fc348/32.png) [@YvorL](https://discuss.elastic.co/u/YvorL)
#### Post date: [September 3, 2020, 10:43am UTC](https://discuss.elastic.co/t/queries-on-ip-range-type-missing-documentation/246445/6 "2020-09-03T10:43:41Z")

</div>

I see, I was trying to avoid that (adding an extra field) if possible. So no CIDR for search.

Thank you again @whatgeorgemade! In this case I use the workarounds for CIDR and do pre+post-processing. I think I'll still skip adding an extra field, since I won't be able to have everything in ES. I'll query the range and process the result set to see if there's an exact match.

---

<div class="post-metadata">

### Author: ![spinscale](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/spinscale/32/25011_2.png) [@spinscale](https://discuss.elastic.co/u/spinscale)
#### Post date: [September 16, 2020, 9:52am UTC](https://discuss.elastic.co/t/queries-on-ip-range-type-missing-documentation/246445/7 "2020-09-16T09:52:41Z")

</div>

If you only have a single IP in your data, then you do not need an iprange as long as your ranges can be expressed using CIDR. You can use the [ip datatype](https://www.elastic.co/guide/en/elasticsearch/reference/7.8/ip.html#query-ip-fields)

```auto
DELETE my-index

PUT my-index
{
  "mappings": {
    "properties": {
      "ip_addr": {
        "type": "ip"
      }
    }
  }
}

PUT my-index/_bulk?refresh
{"index":{}}
{"ip_addr":"192.168.1.1"}
{"index":{}}
{"ip_addr":"1.1.1.1"}
{"index":{}}
{"ip_addr":"10.5.6.7"}

GET my-index/_search
{
  "query": {
    "terms": {
      "ip_addr": [
        "192.168.0.0/16",
        "127.16.0.0/16",
        "10.0.0.0/8"
      ]
    }
  }
}

```

---

<div class="post-metadata">

### Author: ![YvorL](https://avatars.discourse-cdn.com/v4/letter/y/9fc348/32.png) [@YvorL](https://discuss.elastic.co/u/YvorL)
#### Post date: [September 16, 2020, 10:47am UTC](https://discuss.elastic.co/t/queries-on-ip-range-type-missing-documentation/246445/8 "2020-09-16T10:47:23Z")

</div>

Thanks, but I'll need both and want to avoid adding too many fields (or documents) and use different queries. In the long run, I'll see if using ranges was the right move.

---

<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: [October 14, 2020, 10:47am UTC](https://discuss.elastic.co/t/queries-on-ip-range-type-missing-documentation/246445/9 "2020-10-14T10:47:29Z")

</div>

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