Elasticsearch 对日期字段进行条件排序
Elasticsearch conditional sort on date field
我正在尝试对日期字段 registeredAt
上的 Elastic Search 查询结果进行排序。但是,registeredAt
并不存在于所有 returned 的文档中。在那种情况下,我希望排序在替代字段 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'
},
],
然后我希望按从最近到最不最近的顺序 return 对它们进行排序:[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: {...},
},
})
查询运行没有错误,但排序不起作用,文档按索引的顺序return编辑。
我假设 registeredAt
和 invitedAt
在映射中是 date
。
此查询应该有效。我添加的是获取值后调用.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"
}
}
]
}
我正在尝试对日期字段 registeredAt
上的 Elastic Search 查询结果进行排序。但是,registeredAt
并不存在于所有 returned 的文档中。在那种情况下,我希望排序在替代字段 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'
},
],
然后我希望按从最近到最不最近的顺序 return 对它们进行排序:[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: {...},
},
})
查询运行没有错误,但排序不起作用,文档按索引的顺序return编辑。
我假设 registeredAt
和 invitedAt
在映射中是 date
。
此查询应该有效。我添加的是获取值后调用.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"
}
}
]
}