日期字段类型

编辑

JSON 没有日期数据类型,因此 Elasticsearch 中的日期可以是:

  • 包含格式化日期的字符串,例如 "2015-01-01""2015/01/01 12:10:30"
  • 表示自 Epoch 以来的毫秒数的数字。
  • 表示自 Epoch 以来的秒数的数字(配置)。

在内部,日期会转换为 UTC(如果指定了时区),并存储为表示自 Epoch 以来的毫秒数的长整型数字。

如果需要纳秒级分辨率,请使用 date_nanos 字段类型。

对日期的查询在内部会转换为对此长整型表示的范围查询,并且聚合和存储字段的结果会根据与该字段关联的日期格式转换回字符串。

日期始终会呈现为字符串,即使它们最初在 JSON 文档中以长整型形式提供。

日期格式可以自定义,但如果没有指定 format,则使用默认格式。

    "strict_date_optional_time||epoch_millis"

这意味着它将接受带有可选时间戳的日期,这些日期符合 strict_date_optional_time 或自 Epoch 以来的毫秒数支持的格式。

例如

resp = client.indices.create(
    index="my-index-000001",
    mappings={
        "properties": {
            "date": {
                "type": "date"
            }
        }
    },
)
print(resp)

resp1 = client.index(
    index="my-index-000001",
    id="1",
    document={
        "date": "2015-01-01"
    },
)
print(resp1)

resp2 = client.index(
    index="my-index-000001",
    id="2",
    document={
        "date": "2015-01-01T12:10:30Z"
    },
)
print(resp2)

resp3 = client.index(
    index="my-index-000001",
    id="3",
    document={
        "date": 1420070400001
    },
)
print(resp3)

resp4 = client.search(
    index="my-index-000001",
    sort={
        "date": "asc"
    },
)
print(resp4)
response = client.indices.create(
  index: 'my-index-000001',
  body: {
    mappings: {
      properties: {
        date: {
          type: 'date'
        }
      }
    }
  }
)
puts response

response = client.index(
  index: 'my-index-000001',
  id: 1,
  body: {
    date: '2015-01-01'
  }
)
puts response

response = client.index(
  index: 'my-index-000001',
  id: 2,
  body: {
    date: '2015-01-01T12:10:30Z'
  }
)
puts response

response = client.index(
  index: 'my-index-000001',
  id: 3,
  body: {
    date: 1_420_070_400_001
  }
)
puts response

response = client.search(
  index: 'my-index-000001',
  body: {
    sort: {
      date: 'asc'
    }
  }
)
puts response
{
	res, err := es.Indices.Create(
		"my-index-000001",
		es.Indices.Create.WithBody(strings.NewReader(`{
	  "mappings": {
	    "properties": {
	      "date": {
	        "type": "date"
	      }
	    }
	  }
	}`)),
	)
	fmt.Println(res, err)
}

{
	res, err := es.Index(
		"my-index-000001",
		strings.NewReader(`{
	  "date": "2015-01-01"
	} `),
		es.Index.WithDocumentID("1"),
		es.Index.WithPretty(),
	)
	fmt.Println(res, err)
}

{
	res, err := es.Index(
		"my-index-000001",
		strings.NewReader(`{
	  "date": "2015-01-01T12:10:30Z"
	} `),
		es.Index.WithDocumentID("2"),
		es.Index.WithPretty(),
	)
	fmt.Println(res, err)
}

{
	res, err := es.Index(
		"my-index-000001",
		strings.NewReader(`{
	  "date": 1420070400001
	} `),
		es.Index.WithDocumentID("3"),
		es.Index.WithPretty(),
	)
	fmt.Println(res, err)
}

{
	res, err := es.Search(
		es.Search.WithIndex("my-index-000001"),
		es.Search.WithBody(strings.NewReader(`{
	  "sort": {
	    "date": "asc"
	  }
	}`)),
		es.Search.WithPretty(),
	)
	fmt.Println(res, err)
}
const response = await client.indices.create({
  index: "my-index-000001",
  mappings: {
    properties: {
      date: {
        type: "date",
      },
    },
  },
});
console.log(response);

const response1 = await client.index({
  index: "my-index-000001",
  id: 1,
  document: {
    date: "2015-01-01",
  },
});
console.log(response1);

const response2 = await client.index({
  index: "my-index-000001",
  id: 2,
  document: {
    date: "2015-01-01T12:10:30Z",
  },
});
console.log(response2);

const response3 = await client.index({
  index: "my-index-000001",
  id: 3,
  document: {
    date: 1420070400001,
  },
});
console.log(response3);

const response4 = await client.search({
  index: "my-index-000001",
  sort: {
    date: "asc",
  },
});
console.log(response4);
PUT my-index-000001
{
  "mappings": {
    "properties": {
      "date": {
        "type": "date" 
      }
    }
  }
}

PUT my-index-000001/_doc/1
{ "date": "2015-01-01" } 

PUT my-index-000001/_doc/2
{ "date": "2015-01-01T12:10:30Z" } 

PUT my-index-000001/_doc/3
{ "date": 1420070400001 } 

GET my-index-000001/_search
{
  "sort": { "date": "asc"} 
}

date 字段使用默认的 format

此文档使用纯日期。

此文档包含时间。

此文档使用自 Epoch 以来的毫秒数。

请注意,返回的 sort 值都以自 Epoch 以来的毫秒数表示。

日期将接受带有小数点的数字,如 {"date": 1618249875.123456},但在某些情况下(#70085),我们会丢失这些日期的精度,因此应避免使用它们。

文本日期格式接受的文本字符串以及周日期的计算取决于 Elasticsearch 运行的 JDK 版本。有关更多信息,请参见自定义日期格式

多种日期格式

编辑

可以通过使用 || 作为分隔符来指定多种格式。每个格式将依次尝试,直到找到匹配的格式。第一个格式将用于将自 Epoch 以来的毫秒数值转换回字符串。

resp = client.indices.create(
    index="my-index-000001",
    mappings={
        "properties": {
            "date": {
                "type": "date",
                "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
            }
        }
    },
)
print(resp)
response = client.indices.create(
  index: 'my-index-000001',
  body: {
    mappings: {
      properties: {
        date: {
          type: 'date',
          format: 'yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis'
        }
      }
    }
  }
)
puts response
res, err := es.Indices.Create(
	"my-index-000001",
	es.Indices.Create.WithBody(strings.NewReader(`{
	  "mappings": {
	    "properties": {
	      "date": {
	        "type": "date",
	        "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
	      }
	    }
	  }
	}`)),
)
fmt.Println(res, err)
const response = await client.indices.create({
  index: "my-index-000001",
  mappings: {
    properties: {
      date: {
        type: "date",
        format: "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis",
      },
    },
  },
});
console.log(response);
PUT my-index-000001
{
  "mappings": {
    "properties": {
      "date": {
        "type":   "date",
        "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
      }
    }
  }
}

date 字段的参数

编辑

date 字段接受以下参数:

doc_values

是否应将字段以列式存储方式存储在磁盘上,以便以后用于排序、聚合或脚本编写?接受 true(默认)或 false

format

可以解析的日期格式。默认为 strict_date_optional_time||epoch_millis

locale

解析日期时要使用的区域设置,因为月份在所有语言中没有相同的名称和/或缩写。默认值为 ENGLISH。

ignore_malformed

如果为 true,则忽略格式错误的数字。如果为 false(默认),则格式错误的数字会抛出异常并拒绝整个文档。请注意,如果使用了 script 参数,则无法设置此参数。

index

是否应快速搜索该字段?接受 true(默认)和 false。仅启用 doc_values 的日期字段也可以查询,尽管速度较慢。

null_value

接受配置的 format 中一种格式的日期值,该值将替换任何显式的 null 值。默认为 null,这意味着该字段被视为缺失。请注意,如果使用了 script 参数,则无法设置此参数。

on_script_error

定义在索引时由 script 参数定义的脚本抛出错误时该怎么做。接受 fail(默认),这将导致拒绝整个文档;以及 continue,这将在文档的 _ignored 元数据字段中注册该字段并继续索引。仅当还设置了 script 字段时,才能设置此参数。

script

如果设置此参数,则该字段将索引由此脚本生成的值,而不是直接从源读取值。如果在输入文档中为此字段设置了值,则将拒绝该文档并显示错误。脚本的格式与其运行时等效项相同,并且应发出长整型时间戳。

store

字段值是否应存储并可从 _source 字段单独检索。接受 truefalse(默认)。

meta

有关该字段的元数据。

Epoch 秒

编辑

如果需要将日期作为自 Epoch 以来的秒数发送,请确保 format 列出 epoch_second

resp = client.indices.create(
    index="my-index-000001",
    mappings={
        "properties": {
            "date": {
                "type": "date",
                "format": "strict_date_optional_time||epoch_second"
            }
        }
    },
)
print(resp)

resp1 = client.index(
    index="my-index-000001",
    id="example",
    refresh=True,
    document={
        "date": 1618321898
    },
)
print(resp1)

resp2 = client.search(
    index="my-index-000001",
    fields=[
        {
            "field": "date"
        }
    ],
    source=False,
)
print(resp2)
response = client.indices.create(
  index: 'my-index-000001',
  body: {
    mappings: {
      properties: {
        date: {
          type: 'date',
          format: 'strict_date_optional_time||epoch_second'
        }
      }
    }
  }
)
puts response

response = client.index(
  index: 'my-index-000001',
  id: 'example',
  refresh: true,
  body: {
    date: 1_618_321_898
  }
)
puts response

response = client.search(
  index: 'my-index-000001',
  body: {
    fields: [
      {
        field: 'date'
      }
    ],
    _source: false
  }
)
puts response
const response = await client.indices.create({
  index: "my-index-000001",
  mappings: {
    properties: {
      date: {
        type: "date",
        format: "strict_date_optional_time||epoch_second",
      },
    },
  },
});
console.log(response);

const response1 = await client.index({
  index: "my-index-000001",
  id: "example",
  refresh: "true",
  document: {
    date: 1618321898,
  },
});
console.log(response1);

const response2 = await client.search({
  index: "my-index-000001",
  fields: [
    {
      field: "date",
    },
  ],
  _source: false,
});
console.log(response2);
PUT my-index-000001
{
  "mappings": {
    "properties": {
      "date": {
        "type":   "date",
        "format": "strict_date_optional_time||epoch_second"
      }
    }
  }
}

PUT my-index-000001/_doc/example?refresh
{ "date": 1618321898 }

POST my-index-000001/_search
{
  "fields": [ {"field": "date"}],
  "_source": false
}

这将返回类似以下的日期:

{
  "hits": {
    "hits": [
      {
        "_id": "example",
        "_index": "my-index-000001",
        "_score": 1.0,
        "fields": {
          "date": ["2021-04-13T13:51:38.000Z"]
        }
      }
    ]
  }
}

合成 _source

编辑

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

合成源可以对 date 字段值进行排序。例如

resp = client.indices.create(
    index="idx",
    settings={
        "index": {
            "mapping": {
                "source": {
                    "mode": "synthetic"
                }
            }
        }
    },
    mappings={
        "properties": {
            "date": {
                "type": "date"
            }
        }
    },
)
print(resp)

resp1 = client.index(
    index="idx",
    id="1",
    document={
        "date": [
            "2015-01-01T12:10:30Z",
            "2014-01-01T12:10:30Z"
        ]
    },
)
print(resp1)
const response = await client.indices.create({
  index: "idx",
  settings: {
    index: {
      mapping: {
        source: {
          mode: "synthetic",
        },
      },
    },
  },
  mappings: {
    properties: {
      date: {
        type: "date",
      },
    },
  },
});
console.log(response);

const response1 = await client.index({
  index: "idx",
  id: 1,
  document: {
    date: ["2015-01-01T12:10:30Z", "2014-01-01T12:10:30Z"],
  },
});
console.log(response1);
PUT idx
{
  "settings": {
    "index": {
      "mapping": {
        "source": {
          "mode": "synthetic"
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "date": { "type": "date" }
    }
  }
}
PUT idx/_doc/1
{
  "date": ["2015-01-01T12:10:30Z", "2014-01-01T12:10:30Z"]
}

将变为

{
  "date": ["2014-01-01T12:10:30.000Z", "2015-01-01T12:10:30.000Z"]
}