ElasticSearch:在两个不同的范围内搜索,每个范围都有不同的聚合

时间:2016-11-04 16:31:50

标签: elasticsearch

这是一个奇怪的问题,但我试图避免两次调用ES以从两个不同的时间范围获取不同的数据。 让我们说:

从“2016-10-01到2016-10-31”我想将字段“orders.total_sales”(只是一个例子)和另一笔“reviews.count”汇总。

从“2016-09-01到2016-09-30” 我只想总结“orders.total_sales”。

(事实上我需要在第一个范围内进行50次总和聚合),但对于第二个范围,我只需要2)。

我知道可以使用should而不是must来过滤两个范围的任何内容。但是有可能将结果与每个范围区分开来以便与它们一起运行(聚合总和)。

我不认为这是可能的,但以防万一有人以前遇到过这个问题。

提前致谢。

2 个答案:

答案 0 :(得分:2)

您可以使用filter aggregation来实现此目的。您基本上可以为两个不同的范围编写两个过滤器,然后根据需要进行子聚合。

{
  "size": 0,
  "aggs": {
    "range_one": {
      "filter": {
        "range": {
          "your_date_field": {
            "gte": "2016-01-01",
            "lte": "2016-02-02"
          }
        }
      },
      "aggs": {
        "sum_orders": {
          "sum": {
            "field": "your_sum_field1"
          }
        }
      }
    },
    "range_two": {
      "filter": {
        "range": {
          "your_date_field": {
            "gte": "2016-02-01",
            "lte": "2016-03-02"
          }
        }
      },
      "aggs": {
        "sum_orders": {
          "sum": {
            "field": "your_sum_field2"
          }
        }
      }
    }
  }
}

答案 1 :(得分:0)

我最终写了这样的东西(由于ES错误,直到我开始工作)

非常感谢!它有效,但不是过滤器,但想法是一样的 我做了这样的事情:

{
  "timeout" : 1500,
  "query" : {
    "bool" : {
      "must" : [
        {
          "term" : {
            "businessId" : "101598"
          }
        }  ,
        {
          "range" : {
            "date" : {
              "from" : "2016-10-15T03:00:00.000Z",
              "to" : "2016-10-31T03:00:00.000Z",
              "include_lower" : true,
              "include_upper" : true
            }
          }
        }]
    }
  },
  "aggs": {
    "range_one": {
      "date_range": {
        "field": "date",
        "ranges": [
          {
            "from": "2016-10-15T03:00:00.000Z",
            "to": "2016-10-22T03:00:00.000Z" 
          }
        ]
      },
      "aggs": {
        "sum_orders_sales": {
          "sum": {
            "field": "orders.totalSales"
          }
        }
      }
    },
    "range_two": {
      "date_range": {
        "field": "date",
        "ranges": [
          {
            "from": "2016-10-23T03:00:00.000Z",
            "to": "2016-10-31T03:00:00.000Z" 
          }                    
        ]
      },
      "aggs": {
        "sum_orders_count": {
          "sum": {
            "field": "orders.orderCount"
          }
        }
      }
    }
  }
}

在我的情况下,性能和速度很重要,因为我的两个范围是连续的,我想我可以通过business_id(我需要)和从最早的日期(第一个范围的开始日期)到最新的日期(结束)进行过滤第二个范围的日期),假设聚合与查询结果一起工作(否则,它将搜索所有文档,只需让它对只获得一个的结果集进行聚合操作就很棒)。但我是ES的新手,所以不确定我是否正确。然而,它的工作就像魅力一样! 非常感谢1