Elasticsearch 如何在日期时间字段中按时间搜索
Elasticsearch how to search by time in datetime field
我有一个假想索引 test
具有以下映射
PUT test
{"mappings" : {
"properties" : {
"endTs" : {
"type" : "date",
"format": "yyyy-MM-dd HH:mm:ss",
"index": true
},
"startTs" : {
"type" : "date",
"format": "yyyy-MM-dd HH:mm:ss",
"index": true
}
}
}
}
并像下面这样添加一些值
POST _bulk
{ "index" : { "_index" : "test"} }
{ "startTs": "2020-01-01 00:00:00", "endTs": "2020-01-01 00:15:00" }
{ "index" : { "_index" : "test"} }
{ "startTs" : "2020-01-01 00:15:00", "endTs" : "2020-01-01 00:30:00" }
{ "index" : { "_index" : "test"} }
{ "startTs" : "2020-01-01 00:30:00", "endTs" : "2020-01-01 00:45:00" }
{ "index" : { "_index" : "test"} }
{ "startTs" : "2020-01-01 00:45:00", "endTs" : "2020-01-01 01:00:00" }
{ "index" : { "_index" : "test"} }
{ "startTs": "2020-01-01 01:00:00", "endTs": "2020-01-01 01:15:00" }
{ "index" : { "_index" : "test"} }
{ "startTs" : "2020-01-01 01:15:00", "endTs" : "2020-01-01 01:30:00" }
{ "index" : { "_index" : "test"} }
{ "startTs" : "2020-01-01 01:30:00", "endTs" : "2020-01-01 01:45:00" }
{ "index" : { "_index" : "test"} }
{ "startTs" : "2020-01-01 01:45:00", "endTs" : "2020-01-01 02:00:00" }
我的目标是 运行 此 startTs
和 endTs
字段中的一些范围查询。像 startTs: 2020-01-01 00:00:00'
和 endTs: 2020-01-01 00:45:00'
。我只需要使用 time
而不是完整的 datetime
格式进行过滤。所以我尝试了下面的过滤器
GET test/_search
{
"query": {
"bool": {
"must": [
{
"range": {
"startTs": {
"gte": "00:00:00",
"format": "HH:mm:ss"
}
}
},
{
"range": {
"endTs": {
"lte": "00:45:00",
"format": "HH:mm:ss"
}
}
}
]
}
}
}
我预计它将 return 所有记录值小于等于 2020-01-01 00:45:00
{ "startTs": "2020-01-01 00:00:00", "endTs": "2020-01-01 00:15:00" }
{ "startTs" : "2020-01-01 00:15:00", "endTs" : "2020-01-01 00:30:00" }
{ "startTs" : "2020-01-01 00:30:00", "endTs" : "2020-01-01 00:45:00" }
但它根本没有 return 任何东西。
"hits" : {
"total" : {
"value" : 0,
"relation" : "eq"
},
"max_score" : null,
"hits" : [ ]
}
然后我试了
GET test/_search
{
"query": {
"bool": {
"must": [
{
"script": {
"script": {
"source": "doc['startTs'].value.minute >= 0"
}
}
},
{
"script": {
"script": {
"source": "doc['endTs'].value.minute <= 45"
}
}
}
]
}
}
}
它 return 分钟小于等于 45 的所有值,这也不符合预期。
如何运行查询具有时间范围的给定索引?非常感谢任何帮助。
我正在使用 elasticsearch 7.6
我建议您使用自一天开始以来的分钟数或秒数(取决于您需要的分辨率)来索引 date
类型,而不是索引类型。然后 运行 针对该字段的范围查询。
date
类型不支持您要在此处执行的查询类型。
经过大量的尝试,我找到了解决方案。
它对我有用。虽然我对此并不高兴。
GET test/_search
{
"query": {
"bool": {
"must": [
{
"script": {
"script": {
"source": "doc['startTs'].value.hour * 60 + doc['startTs'].value.minute >= 0"
}
}
},
{
"script": {
"script": {
"source": "doc['endTs'].value.hour * 60 + doc['endTs'].value.minute <= 45"
}
}
}
]
}
}
}
仍在寻找更好的解决方案。
我有一个假想索引 test
具有以下映射
PUT test
{"mappings" : {
"properties" : {
"endTs" : {
"type" : "date",
"format": "yyyy-MM-dd HH:mm:ss",
"index": true
},
"startTs" : {
"type" : "date",
"format": "yyyy-MM-dd HH:mm:ss",
"index": true
}
}
}
}
并像下面这样添加一些值
POST _bulk
{ "index" : { "_index" : "test"} }
{ "startTs": "2020-01-01 00:00:00", "endTs": "2020-01-01 00:15:00" }
{ "index" : { "_index" : "test"} }
{ "startTs" : "2020-01-01 00:15:00", "endTs" : "2020-01-01 00:30:00" }
{ "index" : { "_index" : "test"} }
{ "startTs" : "2020-01-01 00:30:00", "endTs" : "2020-01-01 00:45:00" }
{ "index" : { "_index" : "test"} }
{ "startTs" : "2020-01-01 00:45:00", "endTs" : "2020-01-01 01:00:00" }
{ "index" : { "_index" : "test"} }
{ "startTs": "2020-01-01 01:00:00", "endTs": "2020-01-01 01:15:00" }
{ "index" : { "_index" : "test"} }
{ "startTs" : "2020-01-01 01:15:00", "endTs" : "2020-01-01 01:30:00" }
{ "index" : { "_index" : "test"} }
{ "startTs" : "2020-01-01 01:30:00", "endTs" : "2020-01-01 01:45:00" }
{ "index" : { "_index" : "test"} }
{ "startTs" : "2020-01-01 01:45:00", "endTs" : "2020-01-01 02:00:00" }
我的目标是 运行 此 startTs
和 endTs
字段中的一些范围查询。像 startTs: 2020-01-01 00:00:00'
和 endTs: 2020-01-01 00:45:00'
。我只需要使用 time
而不是完整的 datetime
格式进行过滤。所以我尝试了下面的过滤器
GET test/_search
{
"query": {
"bool": {
"must": [
{
"range": {
"startTs": {
"gte": "00:00:00",
"format": "HH:mm:ss"
}
}
},
{
"range": {
"endTs": {
"lte": "00:45:00",
"format": "HH:mm:ss"
}
}
}
]
}
}
}
我预计它将 return 所有记录值小于等于 2020-01-01 00:45:00
{ "startTs": "2020-01-01 00:00:00", "endTs": "2020-01-01 00:15:00" }
{ "startTs" : "2020-01-01 00:15:00", "endTs" : "2020-01-01 00:30:00" }
{ "startTs" : "2020-01-01 00:30:00", "endTs" : "2020-01-01 00:45:00" }
但它根本没有 return 任何东西。
"hits" : {
"total" : {
"value" : 0,
"relation" : "eq"
},
"max_score" : null,
"hits" : [ ]
}
然后我试了
GET test/_search
{
"query": {
"bool": {
"must": [
{
"script": {
"script": {
"source": "doc['startTs'].value.minute >= 0"
}
}
},
{
"script": {
"script": {
"source": "doc['endTs'].value.minute <= 45"
}
}
}
]
}
}
}
它 return 分钟小于等于 45 的所有值,这也不符合预期。
如何运行查询具有时间范围的给定索引?非常感谢任何帮助。
我正在使用 elasticsearch 7.6
我建议您使用自一天开始以来的分钟数或秒数(取决于您需要的分辨率)来索引 date
类型,而不是索引类型。然后 运行 针对该字段的范围查询。
date
类型不支持您要在此处执行的查询类型。
经过大量的尝试,我找到了解决方案。
它对我有用。虽然我对此并不高兴。
GET test/_search
{
"query": {
"bool": {
"must": [
{
"script": {
"script": {
"source": "doc['startTs'].value.hour * 60 + doc['startTs'].value.minute >= 0"
}
}
},
{
"script": {
"script": {
"source": "doc['endTs'].value.hour * 60 + doc['endTs'].value.minute <= 45"
}
}
}
]
}
}
}
仍在寻找更好的解决方案。