一旦我们排除了 doc upserts/updates,基本上有两种方法可以解决这个问题:script_fields 或 filter aggregations。
我们首先假设您的映射类似于:
{
"mappings": {
"properties": {
"delivery_datetime": {
"type": "object",
"properties": {
"dateOnly": {
"type": "date",
"format": "dd.MM.yyyy"
}
}
}
}
}
}
现在,如果我们通过它的 ID 过滤我们所有的包并想知道它处于哪个到期状态,我们可以创建 3 个脚本字段,如下所示:
GET parcels/_search
{
"_source": "timeframe_*",
"script_fields": {
"timeframe_due": {
"script": {
"source": "doc['delivery_datetime.dateOnly'].value.dayOfMonth == params.nowDayOfMonth",
"params": {
"nowDayOfMonth": 8
}
}
},
"timeframe_overdue": {
"script": {
"source": "doc['delivery_datetime.dateOnly'].value.dayOfMonth < params.nowDayOfMonth",
"params": {
"nowDayOfMonth": 8
}
}
},
"timeframe_not_due": {
"script": {
"source": "doc['delivery_datetime.dateOnly'].value.dayOfMonth > params.nowDayOfMonth",
"params": {
"nowDayOfMonth": 8
}
}
}
}
}
这将返回类似于以下内容的内容:
...
"fields" : {
"timeframe_due" : [
true
],
"timeframe_not_due" : [
false
],
"timeframe_overdue" : [
false
]
}
这是微不足道的,日期数学有一个明显的弱点,下面将解决。
或者,我们可以使用 3 个过滤器聚合并类似地仅过滤 1 个有问题的文档,如下所示:
GET parcels/_search
{
"size": 0,
"query": {
"ids": {
"values": [
"my_id_thats_due_today"
]
}
},
"aggs": {
"due": {
"filter": {
"range": {
"delivery_datetime.dateOnly": {
"gte": "now/d",
"lte": "now/d"
}
}
}
},
"overdue": {
"filter": {
"range": {
"delivery_datetime.dateOnly": {
"lt": "now/d"
}
}
}
},
"not_due": {
"filter": {
"range": {
"delivery_datetime.dateOnly": {
"gt": "now/d"
}
}
}
}
}
}
屈服
...
"aggregations" : {
"overdue" : {
"doc_count" : 0
},
"due" : {
"doc_count" : 1
},
"not_due" : {
"doc_count" : 0
}
}
现在第二种方法的优点如下:
-
不涉及脚本 -> 执行速度更快。
-
更重要的是,您不必担心像 12 月 15 日这样的月中日期计算会晚于 11 月 20 日,但微不足道的月中日期比较会产生其他结果。您可以在脚本中实现类似的功能,但更复杂的执行速度会更慢。
-
您可以放弃 ID 过滤并在内部仪表板中使用这些汇总计数。甚至可能是客户仪表板,但普通客户很少有大量可以合理汇总的包裹。