我正在尝试对日期字段上的弹性搜索查询结果进行排序,registeredAt
.但是,registeredAt
并不存在于返回的所有文档中。在这种情况下,我希望排序在替代字段上查找日期,invitedAt
.
如果我们有 3 次点击,如下所示:
hits = [
{
id: 'hit2'
registeredAt: '2021-06-01T23:00:00.000Z',
invitedAt: '2021-05-31T23:00:00.000Z'
},
{
id: 'hit3'
invitedAt: '2021-05-31T23:00:00.000Z'
},
{
id: 'hit1'
invitedAt: '2021-06-04T23:00:00.000Z'
},
],
那么我希望排序按从最近到最近的顺序返回它们:[hit1, hit2, hit3]
. 在每个文档中,排序脚本应查找registeredAt
字段并将该日期作为排序值,如果该字段不存在,则查看invitedAt
的值并将其作为排序值。 从这个意义上说,hit1
没有registeredAt
,并且有最近的invitedAt
日期,因此应该排在第一位。hit2
有一个registeredAt
字段,并且该字段的日期比hit3
的invitedAt
日期(没有registeredAt
字段)更新。
我这样写了查询:
client.search({
index: 'users',
track_total_hits: true,
sort: {
_script: {
type: 'number',
script: {
lang: 'painless',
source:
"if (!doc.containsKey('registeredAt') || doc['registeredAt'].empty) { return doc['invitedAt'].value; } else { return doc['registeredAt'].value }",
},
order: 'desc',
},
},
body: {
from: skip,
size: limit,
query: {...},
},
})
查询运行时没有错误,但排序不起作用,并且文档将按其编制索引的顺序返回。
我假设映射中date
registeredAt
和invitedAt
。 此查询应该有效。我添加的是获取值后调用.getMillis()
。
{
"sort": [
{
"_script": {
"type": "number",
"script": {
"lang": "painless",
"source": """
if (!doc.containsKey('registeredAt') || doc['registeredAt'].empty) {
return doc['invitedAt'].value.getMillis();
}
else {
return doc['registeredAt'].value.getMillis();
}
"""
},
"order": "desc"
}
}
]
}
编辑:.getMillis()
在版本 7.x 中已弃用。 应改用.toInstant().toEpochMilli()
。
这是查询:
{
"sort": [
{
"_script": {
"type": "number",
"script": {
"lang": "painless",
"source": """
if (!doc.containsKey('registeredAt') || doc['registeredAt'].empty) {
return doc['invitedAt'].value.toInstant().toEpochMilli();
}
else {
return doc['registeredAt'].value.toInstant().toEpochMilli();
}
"""
},
"order": "desc"
}
}
]
}