使用 ElasticSearch 按给定数组排序
With ElasticSearch sort by given array
我在 ElasticRearch 中存储了一系列提要。每个提要都有发布此类提要的演员和发布日期。在另一个地方,我以这种方式为每个演员存储一个加权值:
weights: [{'id': 'mark', 'weight': 1}, {'id': 'jane', 'weight': 3}]
我需要查询按日期分组但按此类权重排序的提要。我尝试使用 painless 制作排序功能,但我坚持定义权重:
{
"size": 0,
"query": {
"bool": {
"should": [
{
"bool": {
"must": [
{
"term": {
"actor.id": "mark"
}
},
{
"range": {
"published": {"gte": "2017-09-30T15:37:21.530483"}
}
}
]
}
},
{
"bool": {
"must": [
{
"term": {
"actor.id": "jane"
}
},
{
"range": {
"published": {"gte": "2017-09-30T15:37:21.530483"}
}
}
]
}
}
]
}
},
"aggs": {
"dates": {
"terms": {
"field": "published_date",
},
"aggs": {
"top_verbs_hits": {
"top_hits": {
"sort": {
"_script": {
"type": "number",
"script": {
"lang": "painless",
"source": "def weights = [{'id': 'mark', 'weight': 1}, {'id': 'jane', 'weight': 3}]; def weight = 0; for (int i = 0; i < weights.length; ++i) { if (weights[i].id == doc.actor.id) return weights[i].weight; } return weight;"
},
"order": "asc"
}
},
"_source": {
"includes": ["published", "actor", "object", "target", "extra"]
},
"size": 100
}
}
}
}
},
"sort": [
{
"published": {
"order": "desc"
}
}
],
}
为清楚起见,无痛功能如下:
def weights = [{'id': 'mark', 'weight': 1}, {'id': 'jane', 'weight': 3}];
def weight = 0;
for (int i = 0; i < weights.length; ++i)
{
if (weights[i].id == doc.actor.id)
return weights[i].weight;
}
return weight;
Elastic 在数组定义附近给我一个编译错误。我的猜测是我无法定义 list/array 个 JSON 个对象:
compile error","script_stack":["def weights = [{'id': 'mark', 'weight ..."," ^---- HERE"]....
是否有任何方法可以使用或不使用排序脚本来完成此操作?
Painless 不是 javascript 类语言。您不能只使用类似 JSON 的语法定义数组。
您可以获得阵列的完整文档 here。
您还有一个创建地图来表示您的 JSON 对象。
但在您的情况下,您应该明确使用 scripts params
你能试试这样的东西吗:
"sort": {
"_script": {
"type": "number",
"script": {
"lang": "painless",
"source": "def weight = 0; for (int i = 0; i < params.weights.length; ++i) { if (params.weights[i].id == doc['actor.id'].value) return params.weights[i].weight; } return weight;"
"params": {
"weights" :[{'id': 'mark', 'weight': 1}, {'id': 'jane', 'weight': 3}]
}
},
"order": "asc"
}
}
通过使用参数,您可以使用 JSON 语法定义您的条目数据,而且您还允许 elasticsearch 缓存脚本的编译版本,因为即使权重数组发生变化,源代码也将保持不变.
我在 ElasticRearch 中存储了一系列提要。每个提要都有发布此类提要的演员和发布日期。在另一个地方,我以这种方式为每个演员存储一个加权值:
weights: [{'id': 'mark', 'weight': 1}, {'id': 'jane', 'weight': 3}]
我需要查询按日期分组但按此类权重排序的提要。我尝试使用 painless 制作排序功能,但我坚持定义权重:
{
"size": 0,
"query": {
"bool": {
"should": [
{
"bool": {
"must": [
{
"term": {
"actor.id": "mark"
}
},
{
"range": {
"published": {"gte": "2017-09-30T15:37:21.530483"}
}
}
]
}
},
{
"bool": {
"must": [
{
"term": {
"actor.id": "jane"
}
},
{
"range": {
"published": {"gte": "2017-09-30T15:37:21.530483"}
}
}
]
}
}
]
}
},
"aggs": {
"dates": {
"terms": {
"field": "published_date",
},
"aggs": {
"top_verbs_hits": {
"top_hits": {
"sort": {
"_script": {
"type": "number",
"script": {
"lang": "painless",
"source": "def weights = [{'id': 'mark', 'weight': 1}, {'id': 'jane', 'weight': 3}]; def weight = 0; for (int i = 0; i < weights.length; ++i) { if (weights[i].id == doc.actor.id) return weights[i].weight; } return weight;"
},
"order": "asc"
}
},
"_source": {
"includes": ["published", "actor", "object", "target", "extra"]
},
"size": 100
}
}
}
}
},
"sort": [
{
"published": {
"order": "desc"
}
}
],
}
为清楚起见,无痛功能如下:
def weights = [{'id': 'mark', 'weight': 1}, {'id': 'jane', 'weight': 3}];
def weight = 0;
for (int i = 0; i < weights.length; ++i)
{
if (weights[i].id == doc.actor.id)
return weights[i].weight;
}
return weight;
Elastic 在数组定义附近给我一个编译错误。我的猜测是我无法定义 list/array 个 JSON 个对象:
compile error","script_stack":["def weights = [{'id': 'mark', 'weight ..."," ^---- HERE"]....
是否有任何方法可以使用或不使用排序脚本来完成此操作?
Painless 不是 javascript 类语言。您不能只使用类似 JSON 的语法定义数组。
您可以获得阵列的完整文档 here。 您还有一个创建地图来表示您的 JSON 对象。
但在您的情况下,您应该明确使用 scripts params
你能试试这样的东西吗:
"sort": {
"_script": {
"type": "number",
"script": {
"lang": "painless",
"source": "def weight = 0; for (int i = 0; i < params.weights.length; ++i) { if (params.weights[i].id == doc['actor.id'].value) return params.weights[i].weight; } return weight;"
"params": {
"weights" :[{'id': 'mark', 'weight': 1}, {'id': 'jane', 'weight': 3}]
}
},
"order": "asc"
}
}
通过使用参数,您可以使用 JSON 语法定义您的条目数据,而且您还允许 elasticsearch 缓存脚本的编译版本,因为即使权重数组发生变化,源代码也将保持不变.