我正在尝试使用script_score
的{{1}}创建脚本。
我有几个function_score
字段为rankings
的文档。
该字段的映射是:
type="nested"
示例文档是:
"rankings": {
"type": "nested",
"properties": {
"rank1": {
"type": "long"
},
"rank2": {
"type": "float"
},
"subject": {
"type": "text"
}
}
}
我想要实现的是迭代排名的嵌套对象。实际上,我需要使用ie for循环来查找特定的"rankings": [
{
"rank1": 1051,
"rank2": 78.5,
"subject": "s1"
},
{
"rank1": 45,
"rank2": 34.7,
"subject": "s2"
}]
并使用subject
来计算某些内容。
到目前为止,我使用类似的东西,但它似乎不起作用(抛出编译错误):
rank1, rank2
我也尝试了以下选项:
"function_score": {
"script_score": {
"script": {
"lang": "painless",
"inline":
"sum = 0;"
"for (item in doc['rankings_cug']) {"
"sum = sum + doc['rankings_cug.rank1'].value;"
"}"
}
}
}
循环使用for
代替:
:in
但没有成功。for (item:doc['rankings'])
使用for
循环,但尝试迭代对象的特定元素,即in
:rank1
,它实际编译但似乎找不到一个零长度数组for (item in doc['rankings.rank1'].values)
。我已经读过rank1
元素可以返回类似JSON的对象,但据我发现它在搜索查询中不受支持。
你能告诉我一些如何处理的想法吗?
非常感谢。
答案 0 :(得分:7)
您可以通过params._source
访问_source。这个可行:
PUT /rankings/result/1?refresh
{
"rankings": [
{
"rank1": 1051,
"rank2": 78.5,
"subject": "s1"
},
{
"rank1": 45,
"rank2": 34.7,
"subject": "s2"
}
]
}
POST rankings/_search
POST rankings/_search
{
"query": {
"match": {
"_id": "1"
}
},
"script_fields": {
"script_score": {
"script": {
"lang": "painless",
"inline": "double sum = 0.0; for (item in params._source.rankings) { sum += item.rank2; } return sum;"
}
}
}
}
DELETE rankings
答案 1 :(得分:6)
不幸的是,ElasticSearch脚本一般不支持以这种方式访问嵌套文档的能力(包括Painless)。也许,考虑一种与您的映射不同的结构,如果您需要能够以这种方式迭代排序,则将排名存储在多值字段中。最终,嵌套数据需要去标准化并放入父文档中,以便能够按照此处描述的方式获得分数。
答案 2 :(得分:4)
对于数组中的嵌套对象,迭代项目并且它有效。 以下是我在elasticsearch index中的示例数据:
{
"_index": "activity_index",
"_type": "log",
"_id": "AVjx0UTvgHp45Y_tQP6z",
"_version": 4,
"found": true,
"_source": {
"updated": "2016-12-11T22:56:13.548641",
"task_log": [
{
"week_end_date": "2016-12-11",
"log_hours": 16,
"week_start_date": "2016-12-05"
},
{
"week_start_date": "2016-03-21",
"log_hours": 0,
"week_end_date": "2016-03-27"
},
{
"week_start_date": "2016-04-24",
"log_hours": 0,
"week_end_date": "2016-04-30"
}
],
"created": "2016-12-11T22:56:13.548635",
"userid": 895,
"misc": {
},
"current": false,
"taskid": 1023829
}
}
这是迭代嵌套对象的“无痛”脚本:
{
"script": {
"lang": "painless",
"inline":
"boolean contains(def x, def y) {
for (item in x) {
if (item['week_start_date'] == y){
return true
}
}
return false
}
if(!contains(ctx._source.task_log, params.start_time_param) {
ctx._source.task_log.add(params.week_object)
}",
"params": {
"start_time_param": "2016-04-24",
"week_object": {
"week_start_date": "2016-04-24",
"week_end_date": "2016-04-30",
"log_hours": 0
}
}
}
}
上面用于更新的脚本:/ activity_index / log / AVjx0UTvgHp45Y_tQP6z / _update 在脚本中,创建了一个带有两个参数的名为“contains”的函数。称为功能。 旧的groovy样式:ctx._source.task_log.contains()将无法工作,因为ES 5.X将嵌套对象存储在单独的文档中。希望这有帮助!`