[英]ElasticSearch Painless script: How to iterate in an array of Nested Objects
我正在嘗試使用function_score
的script_score
創建腳本。 我有幾個文件,其rankings
字段是type="nested"
。 該字段的映射是:
"rankings": {
"type": "nested",
"properties": {
"rank1": {
"type": "long"
},
"rank2": {
"type": "float"
},
"subject": {
"type": "text"
}
}
}
示例文檔是:
"rankings": [
{
"rank1": 1051,
"rank2": 78.5,
"subject": "s1"
},
{
"rank1": 45,
"rank2": 34.7,
"subject": "s2"
}]
我想要實現的是迭代嵌套的排名對象。 實際上,我需要使用ie for循環來查找特定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
。 我已經讀過_source
元素是可以返回類似JSON的對象的元素,但據我發現它在搜索查詢中不受支持。
能否請您介紹一下如何繼續這樣做?
非常感謝。
您可以通過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
不幸的是,ElasticSearch腳本通常不支持以這種方式訪問嵌套文檔的能力(包括Painless)。 也許,考慮一種與您的映射不同的結構,如果您需要能夠以這種方式迭代排序,則將排名存儲在多值字段中。 最終,嵌套數據將需要去標准化並放入父文檔中,以便能夠以此處描述的方式獲得分數。
對於數組中的嵌套對象,迭代項目並且它有效。 以下是我在elasticsearch索引中的示例數據:
{
"_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將嵌套對象存儲在單獨的文檔中。 希望這會有所幫助!`
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.