• [ELK实战] 开发中的哪些坑


    方法 / 步骤

    一: 优雅地解决ES字段类型错误问题

    在Elasticsearch中,时间类型是一个非常容易踩坑的数据类型,不按照严格的时间格式,会被识别成text类型
    ES对时间类型的格式的要求是绝对严格的。要求必须是一个标准的UTC时间类型 必须使用yyyy-MM-ddTHH:mm:ssZ格式(其中T个间隔符,Z代表 0 时区)

    1.1 提前手工映射日期类型

    需要通过手工映射方式在索引创建之前指定为日期类型,使用自动映射器无法映射为日期类型。

    “format”: “yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis”,这样就可以避免因为数据格式不统一而导致数据无法写入的窘境

    PUT test_index
    {
      "mappings": {
        "properties": {
          "time": {
            "type": "date",
            "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
          }
        }
      }
    }
    
    

    如果版本在7.11.x及以上版本可以有下面的方案

    1.2 runtime_fields 重新定义的字段

    ❗❗ 实测可用,但做聚合查询会有性能影响,推荐开始时候就定义好准确的字段

    • 在不重新索引数据的情况下向现有文档添加字段
    • 在不了解数据结构的情况下开始处理数据
    • 在查询时覆盖从索引字段返回的值
    • 为特定用途定义字段而不修改底层架构
    GET task1/_search
    {
      "size": 0,
      "runtime_mappings": {
        "day_of_week": {
          "type": "keyword",
          "script": "emit(doc['time'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL,Locale.ROOT))"
        },
        "time": {
          "type": "date",
          "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
        }
      },
      "aggs": {
        //1:按照周统计地震信息,也就是每周有几天地震了
        "week_agg": {
          "date_histogram": {
            "field": "time",
            "calendar_interval": "week"
          },
          "aggs": {
            "week_avg_magnitude": {
              "avg": {
                "field": "magnitude"
              }
            }
          }
        },
        //一周中的每一天的震级
        "day_of_week_magnitude":{
          "terms": {
            "field": "day_of_week"
          },
          "aggs": {
            //2: 一周中每一天的平均地震等级
            "day_of_week_avg_magnitude": {
              "avg": {
                "field": "magnitude"
              }
            }
          }
        }
      }
    }
    
    

    此段代码中,其核心代码如下

    "runtime_mappings": {
        "day_of_week": {
          "type": "keyword",
          "script": "emit(doc['time'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL,Locale.ROOT))"
        },
        "time": {
          "type": "date",
          "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
        }
      }
    

    其在runtime_mappings 中定义了两个“新字段”,即day_of_week和time,其中day_of_week利用运行时字段中执行脚本进行动态计算,从而得出每天分别是一周内的星期几。这种用法可用于各种其他复杂的运算。

    而time字段则是对原有字段进行重新映射,改变其原有字段的类型和其他属性,如format,使其原本不支持的时间类型变为支持。

    参考资料 & 致谢

    [1] ES 中时间日期类型

  • 相关阅读:
    20K+ SRE面试题分享
    Vue使用总结-包括Vue2和Vue3
    隐藏 Tomcat \ Nginx 版本号
    Unity实现设计模式——责任链模式
    信托计划净值数据写入excel
    短视频运营自媒体如何写好一个好的视频脚本?
    正则表达式
    毕设选题推荐基于python的django框架医院预约挂号系统
    医院陪诊小程序:改善患者体验的技术创新
    剑指offer专项突击版第31天
  • 原文地址:https://blog.csdn.net/YangCheney/article/details/125914519