对于要存储在ES中的文档,我想添加脚本参数,这些脚本参数可能与其他存储的参数一起用于过滤和/或排序。这些字段必须在每个查询中计算。
假设原始文档具有字段名称,validFrom,validTo,并使用validFrom和validTo,则必须计算状态字段(如果当前时间在validFrom和validTo之间,则状态为“活动”;如果当前时间为大于“ validTo”,则状态为“已过期”)。 因此,无论过滤条件和排序标准如何,返回的文档都应包含字段名称,validFrom,validTo和status。
为此,我编写了以下脚本:
"script_fields": {
"status": {
"script": {
"lang": "painless",
"source": """
long now = new Date().getTime();
long validToLong = doc["validTo"].value.toInstant().toEpochMilli();
long timeDiff = validToLong - now;
String status = timeDiff > 0 ? "VALID" : "EXPIRED";
status
"""
}
}
}
在某些情况下,仅需要检索有效文档。在这种情况下,我想知道是否有办法以某种方式引用书面脚本,而不是将脚本嵌套到查询语句中并以
方式编写查询"query": {
"match": {
"status": "VALID"
}
}
此外,在某些情况下,状态值可以用于排序,在这种情况下,我想使用上面的脚本。
基本上,在某种情况下,我想编写字段状态脚本,以模拟存储的参数属性。有没有办法做到这一点,或者有没有其他办法可以自动执行某些脚本来计算每个查询中的任意参数,并在某些情况下将这些值与其他存储的参数一起用于过滤/排序?
答案 0 :(得分:1)
我将存储该脚本,然后在脚本字段,脚本过滤器或排序中引用它。
首先存储脚本。您会注意到,我正在检查是否存在参数,这是为了能够在多个上下文中使用相同的脚本,您将立即看到其工作原理
POST _scripts/validity
{
"script": {
"lang": "painless",
"source": """
long now = new Date().getTime();
long validToLong = doc["validTo"].value.toInstant().toEpochMilli();
long timeDiff = validToLong - now;
return params.size() > 0 ? (timeDiff > 0 ? params.valid : params.invalid) : (timeDiff > 0);
"""
}
}
现在,您可以使用script_fields
和filter
发出查询,它们都使用完全相同的脚本并产生所需的结果:
POST valids/_search
{
"script_fields": {
"status": {
"script": {
"id": "validity",
"params": {
"valid": "VALID",
"invalid": "INVALID"
}
}
}
},
"query": {
"script": {
"script": {
"id": "validity"
}
}
}
}
结果:如您所见,只有有效的文档才回来。
"hits" : [
{
"_index" : "valids",
"_type" : "_doc",
"_id" : "_m6Ck24BJvP7VWZfnCC4",
"_score" : 1.0,
"fields" : {
"status" : [
"VALID"
]
}
},
{
"_index" : "valids",
"_type" : "_doc",
"_id" : "_26Ck24BJvP7VWZftyCR",
"_score" : 1.0,
"fields" : {
"status" : [
"VALID"
]
}
}
]
如果您在bool/must_not
查询中添加脚本查询,那么只有无效查询会返回。