Elasticsearch脚本:嵌套日期可以作为日期对象直接访问吗?

问题描述

在我的ES数据中,有nestedparent日期字段。我需要在一个ES无痛脚本中使用这些日期。 parent日期很容易操作,因为它被视为time object。例如,要将parent日期doc['validFrom']转换为UNIX时间数字,我只使用:

doc['validFrom'].value.millis

但是使用nested之类的params._source['offers'][0].validFrom日期进行操作则是另一种情况。这些日期以String而不是date的形式返回。因此,我必须手动将它们解析为date对象:

LocalDateTime.parse(params._source['offers'][0].validFrom),ZoneId.systemDefault()).toInstant().toEpochMilli()

此手动日期解析为脚本带来了额外的复杂性。在我看来,这也不利于性能。可以直接在Elasticsearch脚本中将nested date field作为date object进行访问而无需从String进行解析吗?

P.S 数据示例:

[
    {
        "id": "1","rank": 8,"validFrom": "1970-01-01T00:00:00"
        "offers": [
            {
                "id": "777","rank": 12,"validFrom": "2020-07-06T00:00:00"  // !!! should take the date from here
            }
        ]
    },{
        "id": "2","rank": 35,"validFrom": "2019-05-03T00:00:00"  // !!! should take the date from here as offers are null
        "offers": null
    }
]

我的脚本

    "sort": [
        {
            "_script": {
                "script": {
                    "source": "params._source.offers != null ? zoneddatetime.of(LocalDateTime.parse(params._source['offers'][0].validFrom),ZoneId.systemDefault()).toInstant().toEpochMilli() : doc['validFrom'].value.millis","lang": "painless"
                },"type": "number","order": "asc"
            }
        }
    ]

解决方法

此问题与this one有关。

此处的主题是区分doc_values_source字段。

由于doc_values确实返回原始类型,因此您可以在日期字段上访问.millis。但是_source本身是JSON形式的,未经分析的地图,因此不幸的是,您只能得到最初摄取的内容。

当您遇到性能问题时,建议将嵌套的validFrom提取到顶层,然后将其命名为validFromOverride。这样,您的排序脚本逻辑复杂性将大大降低。

映射和文档结构不需要是不变的。