日期纳秒字段类型

编辑

此数据类型是对 date 数据类型的补充。但是,两者之间存在重要的区别。现有的 date 数据类型以毫秒分辨率存储日期。date_nanos 数据类型以纳秒分辨率存储日期,这限制了其日期范围大约从 1970 年到 2262 年,因为日期仍然存储为自纪元以来的纳秒数的长整型。

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

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

    "strict_date_optional_time_nanos||epoch_millis"

例如

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

resp1 = client.bulk(
    index="my-index-000001",
    refresh=True,
    operations=[
        {
            "index": {
                "_id": "1"
            }
        },
        {
            "date": "2015-01-01"
        },
        {
            "index": {
                "_id": "2"
            }
        },
        {
            "date": "2015-01-01T12:10:30.123456789Z"
        },
        {
            "index": {
                "_id": "3"
            }
        },
        {
            "date": 1420070400000
        }
    ],
)
print(resp1)

resp2 = client.search(
    index="my-index-000001",
    sort={
        "date": "asc"
    },
    runtime_mappings={
        "date_has_nanos": {
            "type": "boolean",
            "script": "emit(doc['date'].value.nano != 0)"
        }
    },
    fields=[
        {
            "field": "date",
            "format": "strict_date_optional_time_nanos"
        },
        {
            "field": "date_has_nanos"
        }
    ],
)
print(resp2)
response = client.indices.create(
  index: 'my-index-000001',
  body: {
    mappings: {
      properties: {
        date: {
          type: 'date_nanos'
        }
      }
    }
  }
)
puts response

response = client.bulk(
  index: 'my-index-000001',
  refresh: true,
  body: [
    {
      index: {
        _id: '1'
      }
    },
    {
      date: '2015-01-01'
    },
    {
      index: {
        _id: '2'
      }
    },
    {
      date: '2015-01-01T12:10:30.123456789Z'
    },
    {
      index: {
        _id: '3'
      }
    },
    {
      date: 1_420_070_400_000
    }
  ]
)
puts response

response = client.search(
  index: 'my-index-000001',
  body: {
    sort: {
      date: 'asc'
    },
    runtime_mappings: {
      date_has_nanos: {
        type: 'boolean',
        script: "emit(doc['date'].value.nano != 0)"
      }
    },
    fields: [
      {
        field: 'date',
        format: 'strict_date_optional_time_nanos'
      },
      {
        field: 'date_has_nanos'
      }
    ]
  }
)
puts response
const response = await client.indices.create({
  index: "my-index-000001",
  mappings: {
    properties: {
      date: {
        type: "date_nanos",
      },
    },
  },
});
console.log(response);

const response1 = await client.bulk({
  index: "my-index-000001",
  refresh: "true",
  operations: [
    {
      index: {
        _id: "1",
      },
    },
    {
      date: "2015-01-01",
    },
    {
      index: {
        _id: "2",
      },
    },
    {
      date: "2015-01-01T12:10:30.123456789Z",
    },
    {
      index: {
        _id: "3",
      },
    },
    {
      date: 1420070400000,
    },
  ],
});
console.log(response1);

const response2 = await client.search({
  index: "my-index-000001",
  sort: {
    date: "asc",
  },
  runtime_mappings: {
    date_has_nanos: {
      type: "boolean",
      script: "emit(doc['date'].value.nano != 0)",
    },
  },
  fields: [
    {
      field: "date",
      format: "strict_date_optional_time_nanos",
    },
    {
      field: "date_has_nanos",
    },
  ],
});
console.log(response2);
PUT my-index-000001
{
  "mappings": {
    "properties": {
      "date": {
        "type": "date_nanos" 
      }
    }
  }
}

PUT my-index-000001/_bulk?refresh
{ "index" : { "_id" : "1" } }
{ "date": "2015-01-01" } 
{ "index" : { "_id" : "2" } }
{ "date": "2015-01-01T12:10:30.123456789Z" } 
{ "index" : { "_id" : "3" } }
{ "date": 1420070400000 } 

GET my-index-000001/_search
{
  "sort": { "date": "asc"}, 
  "runtime_mappings": {
    "date_has_nanos": {
      "type": "boolean",
      "script": "emit(doc['date'].value.nano != 0)" 
    }
  },
  "fields": [
    {
      "field": "date",
      "format": "strict_date_optional_time_nanos" 
    },
    {
      "field": "date_has_nanos"
    }
  ]
}

date 字段使用默认的 format

此文档使用纯日期。

此文档包含时间。

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

请注意,返回的 sort 值都是自纪元以来的纳秒数。

在脚本中使用 .nano 返回日期的纳秒部分。

可以使用 fields 参数在提取数据时指定格式。使用 strict_date_optional_time_nanos,否则你将获得四舍五入的结果。

你还可以指定用 || 分隔的多个日期格式。可以使用与 date 字段相同的映射参数。

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

限制

编辑

即使使用 date_nanos 字段,聚合仍然是毫秒分辨率。此限制也影响 转换


合成 _source

编辑

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

合成源可能会对 date_nanos 字段值进行排序。例如

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

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

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

将变为

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