替代基于elasticsearch中的script_metric聚合对结果进行排序

时间:2016-10-07 12:54:54

标签: sorting elasticsearch

我想根据script_metric聚合的结果对搜索结果进行排序。但总是我得到错误的回应。 我搜索了一下,我发现这是弹性搜索实现的一个限制。它不可能基于script_metric聚合字段进行排序。 另外,我必须对我的结果进行分页,因为它可能会有很多结果。 所以我无法检索所有结果,然后在代码中对结果进行排序。

我想知道这个案子是否有任何好的选择。 这是我在下面的查询

{
  "query": {
    "range": {
      "creationTimestamp": {
        "gte": 1475613000,
        "lte": 1475699400
      }
    }
  },
  "size": 0,
  "aggs": {
    "messages_count": {
      "terms": {
        "field": "sourceId",
        "order": {
          "totalViews": "desc"
        },
        "size": 10
      },
      "aggs": {
        "totalViews": {
          "scripted_metric": {
            "init_script": "_agg['maximum'] = []",
            "map_script": "max = _source.histories[_source.histories.values.size()-1].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;"
          }
        }
      }
    }
  }
}

这里是弹性搜索对我的查询的响应:

{
    "error": {
        "root_cause": [
            {
                "type": "aggregation_execution_exception",
                "reason": "Invalid terms aggregation order path [totalViews]. Terms buckets can only be sorted on a sub-aggregator path that is built out of zero or more single-bucket aggregations within the path and a final single-bucket or a metrics aggregation at the path end."
            }
        ],
        "type": "search_phase_execution_exception",
        "reason": "all shards failed",
        "phase": "query",
        "grouped": true,
        "failed_shards": [
            {
                "shard": 0,
                "index": "datacollection",
                "node": "PS0_HLzxRk-jO_C-_x8ivw",
                "reason": {
                    "type": "aggregation_execution_exception",
                    "reason": "Invalid terms aggregation order path [totalViews]. Terms buckets can only be sorted on a sub-aggregator path that is built out of zero or more single-bucket aggregations within the path and a final single-bucket or a metrics aggregation at the path end."
                }
            }
        ]
    },
    "status": 500
}

1 个答案:

答案 0 :(得分:0)

我找到了解决方案。我阅读了此弹性搜索文档page,并找到了script_metric聚合的替代方法。所以改变内部聚合,一切都很好,工作得很好。

{
  "query": {
    "range": {
      "creationTimestamp": {
        "gte": 1475613000,
        "lte": 1475699400
      }
    }
  },
  "size": 0,
  "aggs": {
    "messages_count": {
      "terms": {
        "field": "sourceId",
        "order": {
          "totalViews": "desc"
        },
        "size" : 10
      },
      "aggs": {
        "totalViews": {
          "sum": {<---- using sum aggregation instead of script_metric, and write my previous script just like this
            "script": "_source.histories[_source.histories.values.size()-1].views"
          }
        }
      }
    }
  }
}