[[number]]
=== Numeric field types
++++
<titleabbrev>Numeric</titleabbrev>
++++

The following numeric types are supported:

[horizontal]
`long`::         A signed 64-bit integer with a minimum value of +-2^63^+ and a maximum value of +2^63^-1+.
`integer`::      A signed 32-bit integer with a minimum value of +-2^31^+ and a maximum value of +2^31^-1+.
`short`::        A signed 16-bit integer with a minimum value of +-32,768+ and a maximum value of +32,767+.
`byte`::         A signed 8-bit integer with a minimum value of +-128+ and a maximum value of +127+.
`double`::       A double-precision 64-bit IEEE 754 floating point number, restricted to finite values.
`float`::        A single-precision 32-bit IEEE 754 floating point number, restricted to finite values.
`half_float`::   A half-precision 16-bit IEEE 754 floating point number, restricted to finite values.
`scaled_float`:: A floating point number that is backed by a `long`, scaled by a fixed `double` scaling factor.
`unsigned_long`:: An unsigned 64-bit integer with a minimum value of 0 and a maximum value of +2^64^-1+.

Below is an example of configuring a mapping with numeric fields:

[source,console]
--------------------------------------------------
PUT my-index-000001
{
  "mappings": {
    "properties": {
      "number_of_bytes": {
        "type": "integer"
      },
      "time_in_seconds": {
        "type": "float"
      },
      "price": {
        "type": "scaled_float",
        "scaling_factor": 100
      }
    }
  }
}
--------------------------------------------------

NOTE: The `double`, `float` and `half_float` types consider that `-0.0` and
`+0.0` are different values. As a consequence, doing a `term` query on
`-0.0` will not match `+0.0` and vice-versa. Same is true for range queries:
if the upper bound is `-0.0` then `+0.0` will not match, and if the lower
bound is `+0.0` then `-0.0` will not match.

==== Which type should I use?

As far as integer types (`byte`, `short`, `integer` and `long`) are concerned,
you should pick the smallest type which is enough for your use-case. This will
help indexing and searching be more efficient. Note however that storage is
optimized based on the actual values that are stored, so picking one type over
another one will have no impact on storage requirements.

For floating-point types, it is often more efficient to store floating-point
data into an integer using a scaling factor, which is what the `scaled_float`
type does under the hood. For instance, a `price` field could be stored in a
`scaled_float` with a `scaling_factor` of +100+. All APIs would work as if
the field was stored as a double, but under the hood Elasticsearch would be
working with the number of cents, +price*100+, which is an integer. This is
mostly helpful to save disk space since integers are way easier to compress
than floating points. `scaled_float` is also fine to use in order to trade
accuracy for disk space. For instance imagine that you are tracking cpu
utilization as a number between +0+ and +1+. It usually does not matter much
whether cpu utilization is +12.7%+ or +13%+, so you could use a `scaled_float`
with a `scaling_factor` of +100+ in order to round cpu utilization to the
closest percent in order to save space.

If `scaled_float` is not a good fit, then you should pick the smallest type
that is enough for the use-case among the floating-point types: `double`,
`float` and `half_float`. Here is a table that compares these types in order
to help make a decision.

[cols="<,<,<,<",options="header",]
|=======================================================================
|Type |Minimum value |Maximum value |Significant bits / digits
|`double`|+2^-1074^+ |+(2-2^-52^)·2^1023^+ |+53+ / +15.95+
|`float`|+2^-149^+ |+(2-2^-23^)·2^127^+ |+24+ / +7.22+
|`half_float`|+2^-24^+ |+65504+ |+11+ / +3.31+
|=======================================================================

[TIP]
.Mapping numeric identifiers
====
// tag::map-ids-as-keyword[]
Not all numeric data should be mapped as a <<number,numeric>> field data type.
{es} optimizes numeric fields, such as `integer` or `long`, for
<<query-dsl-range-query,`range`>> queries. However, <<keyword,`keyword`>> fields
are better for <<query-dsl-term-query,`term`>> and other
<<term-level-queries,term-level>> queries.

Identifiers, such as an ISBN or a product ID, are rarely used in `range`
queries. However, they are often retrieved using term-level queries.

Consider mapping a numeric identifier as a `keyword` if:

* You don't plan to search for the identifier data using 
  <<query-dsl-range-query,`range`>> queries.
* Fast retrieval is important. `term` query searches on `keyword` fields are
  often faster than `term` searches on numeric fields.

If you're unsure which to use, you can use a <<multi-fields,multi-field>> to map
the data as both a `keyword` _and_ a numeric data type.
// end::map-ids-as-keyword[]
====

[[number-params]]
==== Parameters for numeric fields

The following parameters are accepted by numeric types:

[horizontal]

<<coerce,`coerce`>>::

    Try to convert strings to numbers and truncate fractions for integers.
    Accepts `true` (default) and `false`. Not applicable for `unsigned_long`.
    Note that this cannot be set if the `script` parameter is used.

<<mapping-boost,`boost`>>::

    Mapping field-level query time boosting. Accepts a floating point number, defaults
    to `1.0`.

<<doc-values,`doc_values`>>::

    Should the field be stored on disk in a column-stride fashion, so that it
    can later be used for sorting, aggregations, or scripting? Accepts `true`
    (default) or `false`.

<<ignore-malformed,`ignore_malformed`>>::

    If `true`, malformed numbers are ignored. If `false` (default), malformed
    numbers throw an exception and reject the whole document.  Note that this
    cannot be set if the `script` parameter is used.

<<mapping-index,`index`>>::

    Should the field be searchable? Accepts `true` (default) and `false`.

<<null-value,`null_value`>>::

    Accepts a numeric value of the same `type` as the field which is
    substituted for any explicit `null` values. Defaults to `null`, which
    means the field is treated as missing. Note that this cannot be set
    if the `script` parameter is used.

`on_script_error`::

    Defines what to do if the script defined by the `script` parameter
    throws an error at indexing time. Accepts `fail` (default), which
    will cause the entire document to be rejected, and `continue`, which
    will register the field in the document's
    <<mapping-ignored-field,`_ignored`>> metadata field and continue
    indexing. This parameter can only be set if the `script` field is
    also set.

`script`::

    If this parameter is set, then the field will index values generated
    by this script, rather than reading the values directly from the
    source. If a value is set for this field on the input document, then
    the document will be rejected with an error.
    Scripts are in the same format as their
    <<runtime-mapping-fields,runtime equivalent>>. Scripts can only be
    configured on `long` and `double` field types.

<<mapping-store,`store`>>::

    Whether the field value should be stored and retrievable separately from
    the <<mapping-source-field,`_source`>> field. Accepts `true` or `false`
    (default).

<<mapping-field-meta,`meta`>>::

    Metadata about the field.

[[scaled-float-params]]
==== Parameters for `scaled_float`

`scaled_float` accepts an additional parameter:

[horizontal]

`scaling_factor`::

    The scaling factor to use when encoding values. Values will be multiplied
    by this factor at index time and rounded to the closest long value. For
    instance, a `scaled_float` with a `scaling_factor` of +10+ would internally
    store +2.34+ as +23+ and all search-time operations (queries, aggregations,
    sorting) will behave as if the document had a value of +2.3+. High values
    of `scaling_factor` improve accuracy but also increase space requirements.
    This parameter is required.
