Elasticsearch聚合每个文档的列表

时间:2018-03-16 17:33:09

标签: elasticsearch

我将带有时间戳的客户购买存储在Elasticsearch中,作为每个用户的列表:

{
    "_index": "test",
    "_type": "users",
    "_id": "1",
    "_score": 1,
    "_source": {
      "plist": [
        {
          "date": "2017-03-04 15:20:00",
          "price": "57.20"
        },
        {
          "date": "2017-03-05 10:20:00",
          "price": "34.00"
        }
      ]
    }
  }
}
{
    "_index": "test",
    "_type": "users",
    "_id": "2",
    "_score": 1,
    "_source": {
      "plist": [
        {
          "date": "2017-04-04 10:20:00",
          "price": "7.00"
        },
        {
          "date": "2017-04-05 10:20:00",
          "price": "4.00"
        },
        {
          "date": "2017-04-06 10:20:00",
          "price": "54.00"
        }
      ]
    }
  }

如何计算过去7天的平均购买金额,购买次数和每位用户的总金额?

1 个答案:

答案 0 :(得分:0)

如果可以选择重建索引,请将数据更改为:

{
    "_index": "test",
    "_type": "users",
    "_id": "1",
    "_score": 1,
    "_source": {
      "user_id": 1
      "date": "2017-03-04 15:20:00",
      "price": 57.20
    }
}
{
    "_index": "test",
    "_type": "users",
    "_id": "2",
    "_score": 1,
    "_source": {
      "user_id": 1
      "date": "2017-03-05 10:20:00",
      "price": 34.00
    }
}
{
    "_index": "test",
    "_type": "users",
    "_id": "3",
    "_score": 1,
    "_source": {
      "user_id": 2
      "date": "2017-04-04 10:20:00",
      "price": 7.00
    }
}
...

然后你可以像这样运行查询:

GET test/users/_search
{
  "query": {
    "bool": {
      "filter": {
        "range": {
          "date": {
            "gte": "now() - 7d"
          }
        }
      }
    }
  }, 
  "aggs": {
    "users": {
      "terms": {
        "field": "user_id",
        "size": 10
      },
      "aggs": {
        "count": {
          "value_count": {
            "field": "user_id"
          }
        },
        "sum": {
          "sum": {
            "field": "price"
          }
        },
        "average": {
          "avg": {
            "field": "price"
          }
        }
      }
    }
  }
}