在elasticsearch中使用嵌套数组的最大值进行总和聚合

时间:2016-07-20 14:39:59

标签: elasticsearch

我的索引中有以下映射:

{
"testIndex": {
    "mappings": {
        "type1": {
            "properties": {
                "text": {
                    "type": "string"
                },
                "time_views": {
                    "type": "nested",
                    "properties": {
                        "timestamp": {
                            "type": "long"
                        },
                        "views": {
                            "type": "integer"
                        }
                    }
                }
            }
        }
    }
}
}

实际上“time_views”是一个数组,但内部属性不是数组。此嵌套类型包含type1的视图计数历史记录。 “views”是累积属性。

我想查询我的文档,检索文档中“text”字段中任意单词出现的所有文档的“视图”总和。

我知道我应该使用聚合,但我不知道如何进行此查询。

{
    "query": {
        "term":{
            "text": "anyword"
        }
    },
    "size": 0,
    "aggs":{
        ???
    }
}

如上所述,“time_views”是每个文档的数组,我只想使用每个数组的“视图”的最大值。

  

示例数据

{
    "text": "red car",
    "time_views": [
        {
            "timestamp": 1651116565,
            "views": 100
        },
        {
            "timestamp": 1651546456,
            "views": 153
        },
        {
            "timestamp": 165446456,
            "views": 200
        }
    ]
},
{
    "text": "blue car",
    "time_views": [
        {
            "timestamp": 1651116565,
            "views": 20
        },
        {
            "timestamp": 1651546456,
            "views": 70
        },
        {
            "timestamp": 165446456,
            "views": 130
        }
    ]
},
{
    "text": "green car",
    "time_views": [
        {
            "timestamp": 1651116565,
            "views": 4
        },
        {
            "timestamp": 1651546456,
            "views": 86
        },
        {
            "timestamp": 165446456,
            "views": 100
        }
    ]
}

当我查询“car”时,我希望得到以下结果:

{
    "text": "car"
    "views": 430
}

其中430 = 200(第一个doc中的最大值)+ 130(第二个doc中的最大值)+ 100(第三个doc中的最大值)

我不关心结果的Json结构,我只需要这些信息。

那我该怎么办? tnx:)

1 个答案:

答案 0 :(得分:3)

经过多次搜索,我终于找到了解决方案。我使用“scripted_metric”聚合并编写自定义聚合。这是我的代码

{
  "query": {
    "term": {
      "text": "car"
  }
},
"aggs": {
    "views_sum": {
        "scripted_metric": {
            "init_script": "_agg['maximum'] = []",
            "map_script": "max = _source.time_views[0].views; for(tv in _source.time_views){ if(tv.views > max){max = tv.views; }}; _agg.maximum.add(max);",
            "combine_script": "sum = 0; for (m in _agg.maximum) { sum += m }; return sum;",
            "reduce_script": "sum = 0; for (a in _aggs) { sum += a }; return sum;"
        }
    }
},
"size": 0
}

这是我的结果:

{
"took": 3,
"timed_out": false,
"_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
},
"hits": {
    "total": 3,
    "max_score": 0,
    "hits": []
},
"aggregations": {
    "views_sum": {
        "value": 430
    }
}
}