elasticsearch json聚合搜索

新手上路,请多包涵

现在有一个需求,需要对用户操作进行统计,因为数据丢在mysql里面必定会有很大的数据量,所以准备用elasticsearch。目前碰到一个问题,直接贴出结构

{
  "_index": "test_vpn_operation-2018-04-08",
  "_type": "vpn_operation",
  "_id": "AWKiw45UfMhbLGkLP-v3",
  "_score": null,
  "_source": {
    "app_version": "2.0.0",
    "dateline": 1523149062,
    "channel": "pc",
    "edition": "jichu",
    "message": "{\"date_time\":\"2018-04-08T08:59:07\",\"account_id\":447189,\"operation\":[{\"account_id\":\"447189\",\"operation_id\":1,\"timestamp\":1523149062},{\"account_id\":\"447189\",\"operation_id\":1,\"timestamp\":1523149063}],\"channel\":\"pc\",\"edition\":\"jichu\",\"app_version\":\"2.0.0\",\"dateline\":1523149062}",
    "type": "vpn_operation",
    "path": "/data/wwwroot/vpnApi/elklog/vpn_operation_record_20180408",
    "@timestamp": "2018-04-08T00:59:07.722Z",
    "account_id": 447189,
    "date_time": "2018-04-08T08:59:07",
    "@version": "1",
    "host": "JG-otter",
    "operation": [
      {
        "operation_id": 1,
        "account_id": "447189",
        "timestamp": 1523149062
      },
      {
        "operation_id": 1,
        "account_id": "447189",
        "timestamp": 1523149063
      }
    ]
  },
  "fields": {
    "date_time": [
      1523177947000
    ],
    "@timestamp": [
      1523149147722
    ]
  },
  "highlight": {
    "message": [
      "{\"date_time\":\"2018-04-08T08:59:@kibana-highlighted-field@07@/kibana-highlighted-field@\",\"account_id\":447189,\"operation\":[{\"account_id\":\"447189\",\"operation_id\":1,\"timestamp\":1523149062},{\"account_id\":\"447189\",\"operation_id\":1,\"timestamp\":1523149063}],\"channel\":\"pc\",\"edition\":\"jichu\",\"app_version\":\"2.0.0\",\"dateline\":1523149062}"
    ]
  },
  "sort": [
    1523149147722
  ]
}

本来想通过聚合operation.operation_id实现mysql类似于group by的统计操作,但是发现数据不准确。因为operation下面并不存在operation_id这个字段,有什么方法可以达到类似的需求,或者我这边需要如何调整结构,以实现需求

阅读 2.9k
1 个回答

猜测1: 你是不是设置 mapping 的时候, 对该对象数组采用了 object 类型的索引, 这应该就是应对嵌套文档的默认策略. 如果使用的是 object 类型的索引, 那么对象数组会被拍平. 参见如下三篇官方文档:

内部对象数组
嵌套对象
嵌套对象映射

猜测2: 是不是你的一部分文档没有 operation.operation_id 这个字段, 导致结果不准确. 这时可以对该字段设置默认值. 官方文档: missing value

猜测3: 是不是 operation.operation_id 这个字段在所有文档中有多种类型. 比如最开始存了 int, 后来存了 string. 我反正常干这事, 因为我的上游数据源是日志, 日志里的字段更改是常事. 我的做法是, 只查更改后的那部分索引, 因为: mapping 更改规则生效是在新索引建立, 比如3月1日改 mapping, 那么 index-2018-03-02 这个索引规则才会生效, 此时如果跨索引查询, 比如查询整个3月, 则会出问题. 此时可以查询3月2日至3月31日.

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进