簡體   English   中英

ElasticSearch無痛腳本:如何迭代嵌套對象數組

[英]ElasticSearch Painless script: How to iterate in an array of Nested Objects

我正在嘗試使用function_scorescript_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;"
                 "}"
         }
    }
}

我也嘗試了以下選項:

  1. for循環使用:代替infor (item:doc['rankings'])沒有成功。
  2. for使用循環in ,但試圖遍歷對象的特定元件,即,在rank1for (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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM