ElasticSearch脚本,用于计算对象数组的统计信息(作为重新索引或按查询更新的一部分)

时间:2017-03-20 14:25:58

标签: elasticsearch

我在ES中存储了以下文档。

映射:

"sessions_v4": {
"mappings": {
  "perfData": {
    "properties": {
      "perfSamples": {
        "properties": {
          "perfValue": {
            "type": "long"
          },
          "timestamp": {
            "type": "long"
          }
        }
      },
      "sessionId": {
        "type": "text",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      },
      "version": {
        "type": "long"
      }
    }
  }
}

这是一个带有上述映射的示例文档,

"hits": [
  {
    "_index": "sessions_v4",
    "_type": "perfData",
    "_id": "AVraIIvbQlFV0tfF1gDd",
    "_score": 1,
    "_source": {
      "perfSamples": [
        {
          "perfValue": 19,
          "timestamp": 72
        },
        {
          "perfValue": 29,
          "timestamp": 1072
        },
        {
          "perfValue": 30,
          "timestamp": 2072
        },
        {
          "perfValue": 30,
          "timestamp": 3072
        }, 
        ... 
      ] 
   }

存储了数千个文档,我正在寻找一种方法来计算这些文档上的一些自定义指标,并添加一个带有新计算指标的新字段。例如,我想为每个文档添加“total”perfValue作为新字段“perfTotal”以及“perfSamples”。

我尝试了以下脚本,

GET sessions_v4/perfData/_search
{
  "query": {
    "match_all": {}
  },
  "script_fields": {
    "total_perf": {
      "script": {
        "lang": "painless",
        "inline": "int total = 0; for (int i = 0; i < doc['perfSamples'].length; ++i) { total += i; } return total;"
      }
    }
  }
}

我基本上修改了下面提供的脚本 https://www.elastic.co/guide/en/elasticsearch/reference/master/modules-scripting-painless.html

我收到以下错误,

 {
  "took": 3,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 4,
    "failed": 1,
    "failures": [
      {
        "shard": 0,
        "index": "sessions_v4",
        "node": "PG8xNDX3Q2u-vK6EmRI7Ng",
        "reason": {
          "type": "script_exception",
          "reason": "runtime error",
          "caused_by": {
            "type": "illegal_argument_exception",
            "reason": "No field found for [perfSamples] in mapping with types [perfData]"
          },
          "script_stack": [
            "org.elasticsearch.search.lookup.LeafDocLookup.get(LeafDocLookup.java:80)",
            "i = 0; i < doc[‘perfSamples'].length; ++i) { ",
            "               ^---- HERE"
          ],
          "script": "int total = 0; for (int i = 0; i < doc[‘perfSamples'].length; ++i) { total += i; } return total;",
          "lang": "painless"
        }
      }
    ]
  },
  "hits": {
    "total": 56127,
    "max_score": 1,
    "hits": []
  }
}

有什么想法吗?我们刚刚开始使用ES,所以可能是一个微不足道的问题:)

更新:将脚本更改为以下内容并且有效。

GET sessions_v4/perfData/_search
{
  "query": {
    "match_all": {}
  },
  "script_fields": {
    "total_perf": {
      "script": {
        "lang": "painless",
        "inline": "int total = 0; for (int i = 0; i < doc['perfSamples.perfValue'].values.size(); ++i) { total += i; } return total;"
      }
    }
  }
}

0 个答案:

没有答案