数值字段类型编辑

支持以下数值类型

long

有符号 64 位整数,最小值为 -263,最大值为 263-1

integer

有符号 32 位整数,最小值为 -231,最大值为 231-1

short

有符号 16 位整数,最小值为 -32,768,最大值为 32,767

byte

有符号 8 位整数,最小值为 -128,最大值为 127

double

双精度 64 位 IEEE 754 浮点数,限制为有限值。

float

单精度 32 位 IEEE 754 浮点数,限制为有限值。

half_float

半精度 16 位 IEEE 754 浮点数,限制为有限值。

scaled_float

long 支持的浮点数,按固定的 double 比例因子进行缩放。

unsigned_long

无符号 64 位整数,最小值为 0,最大值为 264-1

以下是使用数值字段配置映射的示例

resp = client.indices.create(
    index="my-index-000001",
    body={
        "mappings": {
            "properties": {
                "number_of_bytes": {"type": "integer"},
                "time_in_seconds": {"type": "float"},
                "price": {"type": "scaled_float", "scaling_factor": 100},
            }
        }
    },
)
print(resp)
response = client.indices.create(
  index: 'my-index-000001',
  body: {
    mappings: {
      properties: {
        number_of_bytes: {
          type: 'integer'
        },
        time_in_seconds: {
          type: 'float'
        },
        price: {
          type: 'scaled_float',
          scaling_factor: 100
        }
      }
    }
  }
)
puts response
res, err := es.Indices.Create(
	"my-index-000001",
	es.Indices.Create.WithBody(strings.NewReader(`{
	  "mappings": {
	    "properties": {
	      "number_of_bytes": {
	        "type": "integer"
	      },
	      "time_in_seconds": {
	        "type": "float"
	      },
	      "price": {
	        "type": "scaled_float",
	        "scaling_factor": 100
	      }
	    }
	  }
	}`)),
)
fmt.Println(res, err)
PUT my-index-000001
{
  "mappings": {
    "properties": {
      "number_of_bytes": {
        "type": "integer"
      },
      "time_in_seconds": {
        "type": "float"
      },
      "price": {
        "type": "scaled_float",
        "scaling_factor": 100
      }
    }
  }
}

doublefloathalf_float 类型认为 -0.0+0.0 是不同的值。因此,对 -0.0 执行 term 查询将不会匹配 +0.0,反之亦然。范围查询也是如此:如果上限是 -0.0,则 +0.0 将不匹配;如果下限是 +0.0,则 -0.0 将不匹配。

我应该使用哪种类型?编辑

就整数类型(byteshortintegerlong)而言,您应该选择足以满足您的用例的最小类型。这将有助于提高索引和搜索效率。但请注意,存储是根据实际存储的值进行优化的,因此选择一种类型而不是另一种类型不会对存储需求产生影响。

对于浮点类型,使用缩放因子将浮点数据存储到整数中通常更高效,这就是 scaled_float 类型在后台所做的。例如,price 字段可以存储在 scaled_float 中,其 scaling_factor100。所有 API 的工作方式都像该字段存储为双精度型一样,但在后台,Elasticsearch 将使用美分数(price*100),这是一个整数。这主要有助于节省磁盘空间,因为整数比浮点数更容易压缩。scaled_float 也适用于以精度换取磁盘空间的情况。例如,假设您正在跟踪 CPU 利用率,它是一个介于 01 之间的数字。CPU 利用率是 12.7% 还是 13% 通常并不重要,因此您可以使用 scaling_factor100scaled_float 将 CPU 利用率四舍五入到最接近的百分比,以节省空间。

如果 scaled_float 不适用,则应从浮点类型(doublefloathalf_float)中选择足以满足用例的最小类型。下表比较了这些类型,以帮助您做出决定。

类型 最小值 最大值 有效
位数 / 数字
示例精度损失

double

2-1074

(2-2-52)·21023

53 / 15.95

1.2345678912345678
1.234567891234568

float

2-149

(2-2-23)·2127

24 / 7.22

1.23456789
1.2345679

half_float

2-24

65504

11 / 3.31

1.2345
1.234375

映射数字标识符

并非所有数字数据都应映射为 数值 字段数据类型。Elasticsearch 优化了数值字段(例如 integerlong),以便进行 范围 查询。但是,关键字 字段更适合 词条 和其他 词条级别 查询。

标识符(例如 ISBN 或产品 ID)很少用于 范围 查询。但是,它们通常使用词条级别查询来检索。

如果满足以下条件,请考虑将数字标识符映射为 keyword

  • 您不打算使用 范围 查询来搜索标识符数据。
  • 快速检索很重要。keyword 字段上的 term 查询搜索通常比数值字段上的 term 搜索更快。

如果您不确定要使用哪个,可以使用 多字段 将数据同时映射为 keyword *和* 数值数据类型。

数值字段的参数编辑

数值类型接受以下参数

coerce
尝试将字符串转换为数字,并截断整数的小数部分。接受 true(默认值)和 false。不适用于 unsigned_long。请注意,如果使用了 script 参数,则无法设置此参数。
doc_values
该字段是否应以列式存储在磁盘上,以便以后用于排序、聚合或脚本?接受 true(默认值)或 false
ignore_malformed
如果为 true,则忽略格式错误的数字。如果为 false(默认值),则格式错误的数字会引发异常并拒绝整个文档。请注意,如果使用了 script 参数,则无法设置此参数。
index
该字段是否应可快速搜索?接受 true(默认值)和 false。仅启用了 doc_values 的数值字段也可以查询,但速度较慢。
meta
有关该字段的元数据。
null_value
接受与该字段相同 类型 的数值,该数值将替换任何显式 null 值。默认为 null,这意味着该字段被视为缺失。请注意,如果使用了 script 参数,则无法设置此参数。
on_script_error
定义如果 script 参数定义的脚本在索引时引发错误,该怎么办。接受 fail(默认值)(这将导致拒绝整个文档)和 continue(这将在文档的 _ignored 元数据字段中注册该字段并继续索引)。仅当还设置了 script 字段时,才能设置此参数。
script
如果设置了此参数,则该字段将索引此脚本生成的值,而不是直接从源读取值。如果在输入文档上为此字段设置了值,则该文档将被拒绝并报错。脚本的格式与其 运行时等效项 相同。脚本只能在 longdouble 字段类型上配置。
store
字段值是否应存储并可与 _source 字段分开检索。接受 truefalse(默认值)。
time_series_dimension

(可选,布尔值)

将该字段标记为 时间序列维度。默认为 false

index.mapping.dimension_fields.limit 索引设置限制了索引中的维度数量。

维度字段具有以下约束

  • doc_valuesindex 映射参数必须为 true
  • 字段值不能是 数组或多值

在数值字段类型中,只有 byteshortintegerlongunsigned_long 字段支持此参数。

数值字段不能同时是时间序列维度和时间序列指标。

time_series_metric

(可选,字符串)将该字段标记为 时间序列指标。该值是指标类型。您无法更新现有字段的此参数。

数值字段的有效 time_series_metric
counter
仅单调递增或重置为 0(零)的累积指标。例如,错误计数或已完成任务数。
gauge
表示可以任意增减的单个数值的指标。例如,温度或可用磁盘空间。
null(默认值)
不是时间序列指标。

对于数值时间序列指标,doc_values 参数必须为 true。数值字段不能同时是时间序列维度和时间序列指标。

scaled_float 的参数编辑

scaled_float 接受一个附加参数

scaling_factor

编码值时使用的缩放因子。值将在索引时乘以该因子并四舍五入到最接近的长整型值。例如,scaled_floatscaling_factor10 时,将在内部将 2.34 存储为 23,并且所有搜索时操作(查询、聚合、排序)的行为都将像文档的值为 2.3 一样。较高的 scaling_factor 值可提高精度,但也会增加空间需求。此参数是必需的。

scaled_float 饱和编辑

scaled_float 存储为单个 long 值,该值是原始值乘以缩放因子的结果。如果乘法结果超出了 long 的范围,则该值将饱和为 long 的最小值或最大值。例如,如果缩放因子为 100 且值为 92233720368547758.08,则预期值为 9223372036854775808。但是,存储的值为 9223372036854775807,即 long 的最大值。

当缩放因子或提供的 float 值非常大时,这可能会导致 范围查询 出现意外结果。

合成 _source编辑

合成 _source 仅适用于 TSDB 索引(index.mode 设置为 time_series 的索引)。对于其他索引,合成 _source 处于技术预览阶段。技术预览版中的功能可能会在未来版本中更改或删除。Elastic 将努力解决任何问题,但技术预览版中的功能不受官方 GA 功能的支持 SLA 的约束。

unsigned_long 之外的所有数字字段在其默认配置中都支持 合成 _source。合成 _source 不能与 ignore_malformedcopy_to 或禁用的 doc_values 一起使用。

合成源始终对数字字段进行排序。例如

resp = client.indices.create(
    index="idx",
    body={
        "mappings": {
            "_source": {"mode": "synthetic"},
            "properties": {"long": {"type": "long"}},
        }
    },
)
print(resp)

resp = client.index(
    index="idx",
    id="1",
    body={"long": [0, 0, -123466, 87612]},
)
print(resp)
response = client.indices.create(
  index: 'idx',
  body: {
    mappings: {
      _source: {
        mode: 'synthetic'
      },
      properties: {
        long: {
          type: 'long'
        }
      }
    }
  }
)
puts response

response = client.index(
  index: 'idx',
  id: 1,
  body: {
    long: [
      0,
      0,
      -123_466,
      87_612
    ]
  }
)
puts response
PUT idx
{
  "mappings": {
    "_source": { "mode": "synthetic" },
    "properties": {
      "long": { "type": "long" }
    }
  }
}
PUT idx/_doc/1
{
  "long": [0, 0, -123466, 87612]
}

将变为

{
  "long": [-123466, 0, 0, 87612]
}

缩放浮点数将始终应用其缩放因子,因此

resp = client.indices.create(
    index="idx",
    body={
        "mappings": {
            "_source": {"mode": "synthetic"},
            "properties": {
                "f": {"type": "scaled_float", "scaling_factor": 0.01}
            },
        }
    },
)
print(resp)

resp = client.index(
    index="idx",
    id="1",
    body={"f": 123},
)
print(resp)
response = client.indices.create(
  index: 'idx',
  body: {
    mappings: {
      _source: {
        mode: 'synthetic'
      },
      properties: {
        f: {
          type: 'scaled_float',
          scaling_factor: 0.01
        }
      }
    }
  }
)
puts response

response = client.index(
  index: 'idx',
  id: 1,
  body: {
    f: 123
  }
)
puts response
PUT idx
{
  "mappings": {
    "_source": { "mode": "synthetic" },
    "properties": {
      "f": { "type": "scaled_float", "scaling_factor": 0.01 }
    }
  }
}
PUT idx/_doc/1
{
  "f": 123
}

将变为

{
  "f": 100.0
}