【Elasticsearch】动手创建一个索引

Elasticsearch索引创建指南

1.创建索引

创建 1 个索引,需满足以下要求:

  • 名称:test-index
  • 别名:log-index
  • 指定为写入索引
  • 尽量包含不同的字段类型,包含中文,开启索引和统计
  • 初始分片数为 3 3 3
  • 副本数为 1 1 1
  • 刷新频率 15 15 15
PUT /test-index
{
  "settings": {
    "number_of_shards": 3,
    "number_of_replicas": 1,
    "refresh_interval": "15s"
  },
  "aliases": {
    "log-index": {
      "is_write_index": true
    }
  },
  "mappings": {
    "properties": {
      "timestamp": {
        "type": "date",
        "format": "yyyy-MM-dd HH:mm:ss||epoch_millis"
      },
      "log_level": {
        "type": "keyword"
      },
      "message": {
        "type": "text",
        "analyzer": "ik_max_word",
        "search_analyzer": "ik_smart",
        "fielddata": true
      },
      "user_id": {
        "type": "long"
      },
      "ip_address": {
        "type": "ip"
      },
      "response_time": {
        "type": "float"
      },
      "status_code": {
        "type": "integer"
      },
      "is_success": {
        "type": "boolean"
      },
      "tags": {
        "type": "keyword"
      },
      "request_body": {
        "type": "text",
        "index": false
      },
      "geo_location": {
        "type": "geo_point"
      },
      "request_count": {
        "type": "integer",
        "doc_values": true
      },
      "metadata": {
        "type": "object",
        "enabled": true
      },
      "create_time": {
        "type": "date"
      }
    }
  }
}

在这里插入图片描述

1.1 关键配置说明

  • 1️⃣ 基础设置
    • number_of_shards: 3 - 3 个主分片
    • number_of_replicas: 1 - 每个主分片 1 个副本
    • refresh_interval: "15s" - 15 秒刷新频率
  • 2️⃣ 别名与写入索引
    • aliases 中定义了 log-index 别名
    • is_write_index: true 指定该别名为写入索引
  • 3️⃣ 字段类型多样性
    • date - 时间戳类型
    • keyword - 精确值类型(日志级别、标签)
    • text - 全文检索类型(支持中文分词)
    • long/integer/float - 数值类型
    • boolean - 布尔类型
    • ip - IP地址类型
    • geo_point - 地理位置类型
    • object - 对象类型
  • 4️⃣ 中文支持与统计
    • 使用 ik_max_wordik_smart 分析器处理中文
    • "fielddata": true"doc_values": true 开启字段数据统计

1.2 重要提示

  • 1️⃣ IK分析器:确保您的 Elasticsearch 已安装 IK 中文分词插件,否则需要移除 analyzer 配置或改用标准分析器。

  • 2️⃣ 索引操作:创建后如需修改设置,可以使用:

    PUT /test-index/_settings
    {
      "refresh_interval": "15s",
      "number_of_replicas": 1
    }
    
  • 3️⃣ 验证索引:创建完成后可以通过以下命令验证:

    GET /test-index
    GET /_cat/indices/test-index?v
    

    在这里插入图片描述

2.摄入管道

PUT /test-index
{
  "settings": {
    "number_of_shards": 3,
    "number_of_replicas": 1,
    "refresh_interval": "15s",
    "index": {
      "default_pipeline": "log-index_pipeline"
    }
  },
  // 其他配置
}

"default_pipeline": "log-index_pipeline" 这行配置的意思是:

为此索引设置一个默认的 摄入管道(Ingest Pipeline),名为 log-index_pipeline

2.1 详细说明

1️⃣ 什么是 Ingest Pipeline(摄入管道)?

  • 它相当于一个 数据处理的流水线中间件
  • 在文档被正式索引(存入磁盘)之前,它可以对文档进行各种预处理和转换。
  • 您可以把它想象成数据库中的 “触发器”(Trigger)或数据处理脚本。

2️⃣ 它是如何工作的?

数据写入的流程会变成这样:您的应用程序 → Elasticsearch → [Ingest Pipeline] → 索引存储

而不是直接的:您的应用程序 → Elasticsearch → 索引存储

3️⃣ 在这个配置中的作用

当您通过 log-index 别名或者直接向 test-index 索引写入数据时,Elasticsearch 会自动将数据先送入名为 log-index_pipeline 的管道进行处理,处理完成后再存入索引。

2.2 一个具体的例子

假设我们有一个管道,用于自动解析日志消息并添加时间戳:

首先,创建这个管道:

PUT _ingest/pipeline/log-index_pipeline
{
  "description": "为日志数据添加处理逻辑",
  "processors": [
    {
      "set": { // 添加一个字段
        "field": "processed_by",
        "value": "log_pipeline"
      }
    },
    {
      "script": { // 使用脚本处理
        "source": """
          // 如果是 ERROR 级别的日志,添加一个告警标签
          if (ctx.log_level == 'ERROR') {
            ctx.tags = ctx.tags ?: [];
            ctx.tags.add('needs_alert');
          }
        """
      }
    }
  ]
}

然后,当您写入数据时:

POST /log-index/_doc
{
  "timestamp": "2024-01-01 12:00:00",
  "log_level": "ERROR",
  "message": "数据库连接失败"
}

最终存入索引的数据会自动变成:

{
  "timestamp": "2024-01-01 12:00:00",
  "log_level": "ERROR",
  "message": "数据库连接失败",
  "processed_by": "log_pipeline", // 管道添加的字段
  "tags": ["needs_alert"] // 管道根据条件添加的标签
}

2.3 潜在用途

考虑到索引名为 test-index,别名是 log-index,这个管道可能被设计用于:

  • 1️⃣ 数据清洗:清理或格式化日志消息
  • 2️⃣ 字段提取:从原始消息中提取出结构化的字段(如从 "用户 [张三] 登录成功" 中提取出用户名 "张三"
  • 3️⃣ 数据丰富:根据 IP 地址添加地理位置信息
  • 4️⃣ 数据转换:将字符串数字转换为真正的数值类型

2.4 重要提醒

❌ 如果您的集群中并不存在名为 log-index_pipeline 的管道,那么这个索引创建命令将会失败!

您有两个选择:

选择一:删除此配置(如果您不需要管道)

PUT /test-index
{
  "settings": {
    "number_of_shards": 3,
    "number_of_replicas": 1,
    "refresh_interval": "15s"
    // 移除了 default_pipeline 配置
  },
  // ... 其他配置保持不变
}

选择二:先创建对应的管道

在执行索引创建命令前,先确保管道存在。

3.数据统计

字段数据统计 主要是指启用 fielddatadoc_values 功能,让 Elasticsearch 能够对文本字段进行 排序、聚合和脚本计算

⭐ 推荐阅读:《【Elasticsearch】映射:fielddata 详解

3.1 两种主要的字段数据机制

3.1.1 Fielddata(字段数据)

主要用于 text 类型的字段。

"message": {
  "type": "text",
  "analyzer": "ik_max_word", 
  "search_analyzer": "ik_smart",
  "fielddata": true  // ← 这就是开启 fielddata
}

作用:让 text 字段支持:

  • 聚合(Aggregations)
  • 排序(Sorting)
  • 脚本计算(Scripting)

代价:会消耗大量 堆内存,因为需要将倒排索引中的数据加载到内存中。

3.1.2 Doc Values(文档值)

主要用于非文本字段,默认开启。

"request_count": {
  "type": "integer",
  "doc_values": true  // ← 默认就是true,显式声明
}

作用:在索引时构建的列式存储,用于:

  • 聚合
  • 排序
  • 脚本

优势:存储在磁盘上,使用时部分加载到内存,更加高效。

3.2 实际例子对比

3.2.1 场景:分析日志消息中的关键词频率

1️⃣ 没有开启 fielddata 时:

// 这个查询会失败!
GET /test-index/_search
{
  "aggs": {
    "popular_messages": {
      "terms": {
        "field": "message"  // ← text字段默认不能聚合
      }
    }
  }
}

错误信息Fielddata is disabled on text fields by default...

2️⃣ 开启 fielddata 后:

// 这个查询可以成功!
GET /test-index/_search
{
  "aggs": {
    "popular_keywords": {
      "terms": {
        "field": "message.keyword"  // 或者使用message字段本身
      }
    }
  }
}

结果:可以统计出哪些关键词在日志中出现最频繁。

3.2.2 在您索引中的具体应用

在您之前的映射中,这些配置都涉及字段数据统计:

{
  "mappings": {
    "properties": {
      "message": {
        "type": "text",
        "analyzer": "ik_max_word",
        "search_analyzer": "ik_smart", 
        "fielddata": true  // ← 开启文本字段数据统计
      },
      "request_count": {
        "type": "integer", 
        "doc_values": true // ← 开启数值字段数据统计(其实默认就是true)
      },
      "log_level": {
        "type": "keyword"   // ← keyword类型默认就有doc_values
      }
    }
  }
}

3.2.3 实际使用场景

1️⃣ 日志级别统计

GET /test-index/_search
{
  "size": 0,
  "aggs": {
    "log_level_distribution": {
      "terms": {
        "field": "log_level"  // ← 依赖字段数据
      }
    }
  }
}

在这里插入图片描述

2️⃣ 响应时间分析

GET /test-index/_search  
{
  "size": 0,
  "aggs": {
    "response_time_stats": {
      "stats": {
        "field": "response_time"  // ← 依赖字段数据
      }
    }
  }
}

在这里插入图片描述

3️⃣ 按消息内容聚合(需要 fielddata

GET /test-index/_search
{
  "size": 0, 
  "aggs": {
    "common_errors": {
      "terms": {
        "field": "message"  // ← 这需要fielddata: true
      }
    }
  }
}

在这里插入图片描述

3.3 性能考虑

特性FielddataDoc Values
存储位置内存(堆)磁盘
构建时机搜索时索引时
内存占用
性能快(全内存)较快

最佳实践

  • 对于 text 字段,尽量避免开启 fielddata,除非确实需要
  • 对于聚合和排序,优先使用 keyword 类型子字段
  • 监控堆内存使用情况

3.4 总结

“开启字段数据统计” 就是通过配置 fielddata: truedoc_values: true,让 Elasticsearch 能够对字段值进行:

  • 聚合分析
  • 排序操作
  • 脚本计算
  • 统计计算

4.索引数据

4.1 核心区别

特性开启索引(Indexing)开启字段数据统计(Fielddata)
控制什么是否 可被搜索是否 可被聚合/排序
配置参数"index": true/false"fielddata": true/false
主要用途全文检索、关键词搜索聚合分析、排序、脚本计算
存储结构倒排索引列式存储(内存或磁盘)

4.2 详细对比

4.2.1 开启索引(Indexing)

控制字段是否被加入 倒排索引,使其可被搜索。

{
  "request_body": {
    "type": "text",
    "index": false  // ← 这个字段不可被搜索
  },
  "message": {
    "type": "text", 
    "index": true   // ← 这个字段可以被搜索(默认就是true)
  }
}

影响

  • "index": false → 该字段 无法被搜索
  • "index": true → 该字段 可以被搜索

例子

// 这个搜索能成功(message字段可搜索)
GET /test-index/_search
{
  "query": {
    "match": {
      "message": "登录"
    }
  }
}

在这里插入图片描述

// 这个搜索会返回空结果(request_body字段不可搜索)  
GET /test-index/_search
{
  "query": {
    "match": {
      "request_body": "某些内容"
    }
  }
}

在这里插入图片描述

4.2.2 开启字段数据统计(Fielddata)

控制是否允许对 text 类型字段进行 聚合、排序 等操作。

{
  "message": {
    "type": "text",
    "fielddata": true  // ← 允许对这个text字段进行聚合和排序
  }
}

影响

  • "fielddata": false → 该字段 无法聚合、排序
  • "fielddata": true → 该字段 可以聚合、排序

例子

// 这个聚合能成功(fielddata: true)
GET /test-index/_search
{
  "aggs": {
    "common_messages": {
      "terms": {
        "field": "message"  // ← 对text字段聚合
      }
    }
  }
}

在这里插入图片描述

// 这个排序能成功(fielddata: true)  
GET /test-index/_search
{
  "sort": [
    {
      "message": {
        "order": "asc"
      }
    }
  ]
}

在这里插入图片描述

4.3 实际场景组合

4.3.1 场景1:只搜索不聚合

{
  "log_message": {
    "type": "text",
    "index": true,      // 可以被搜索
    "fielddata": false  // 但不能聚合排序(默认情况)
  }
}

4.3.2 场景2:只存储不搜索

{
  "raw_data": {
    "type": "text", 
    "index": false,     // 不能被搜索
    "fielddata": false  // 也不能聚合
  }
}

4.3.3 场景3:搜索且聚合(消耗资源)

{
  "analyzed_content": {
    "type": "text",
    "index": true,      // 可以被搜索
    "fielddata": true   // 也可以聚合排序
  }
}

4.3.4 场景4:最佳实践方案

{
  "message": {
    "type": "text",
    "index": true,      // 用于全文搜索
    "fielddata": false, // 避免内存消耗
    "fields": {
      "keyword": {
        "type": "keyword"  // 用于聚合和排序
      }
    }
  }
}

4.4 在您之前配置中的体现

{
  "request_body": {
    "type": "text",
    "index": false       // ← 这个字段关闭了索引(不可搜索)
  },
  "message": {
    "type": "text",
    "analyzer": "ik_max_word",
    "search_analyzer": "ik_smart",
    "fielddata": true    // ← 这个字段开启了字段数据统计(可聚合)
    // 注意:这里没有写 "index",默认为true,所以也可搜索
  }
}

解读

  • request_body不可搜索"index": false
  • message可搜索(默认 "index": true)且 可聚合"fielddata": true

4.5 总结

操作依赖索引
(index: true)
依赖字段数据
(fielddata: trueh)
搜索/查询✅ 必需❌ 不需要
聚合分析❌ 不需要✅ 必需(针对 text 字段)
排序操作❌ 不需要✅ 必需(针对 text 字段)
脚本计算❌ 不需要✅ 必需

简单记忆

  • “开启索引” = 让字段 能被找到
  • “开启字段数据统计” = 让字段 能被分析

5.测试数据

根据您之前定义的 test-index 映射生成 10 条符合格式的测试数据。

POST /test-index/_bulk
{"index":{}}
{"timestamp":"2024-06-15 08:30:25","log_level":"INFO","message":"用户张三登录系统成功","user_id":1001,"ip_address":"192.168.1.100","response_time":45.2,"status_code":200,"is_success":true,"tags":["login","success"],"request_body":"username=zhangsan&password=***","geo_location":{"lat":39.9042,"lon":116.4074},"request_count":1,"metadata":{"browser":"Chrome","version":"120.0"},"create_time":"2024-06-15T08:30:25Z"}
{"index":{}}
{"timestamp":"2024-06-15 08:32:10","log_level":"ERROR","message":"数据库连接超时,请检查网络配置","user_id":1002,"ip_address":"10.0.0.55","response_time":1500.5,"status_code":500,"is_success":false,"tags":["database","timeout","critical"],"request_body":"query=SELECT * FROM users","geo_location":{"lat":31.2304,"lon":121.4737},"request_count":3,"metadata":{"service":"user-service","thread_id":"thread-25"},"create_time":"2024-06-15T08:32:10Z"}
{"index":{}}
{"timestamp":"2024-06-15 08:35:42","log_level":"WARN","message":"内存使用率超过80%阈值","user_id":null,"ip_address":"172.16.10.20","response_time":0.5,"status_code":200,"is_success":true,"tags":["monitoring","memory"],"request_body":"","geo_location":{"lat":23.1291,"lon":113.2644},"request_count":1,"metadata":{"hostname":"server-01","memory_usage":82},"create_time":"2024-06-15T08:35:42Z"}
{"index":{}}
{"timestamp":"2024-06-15 08:40:15","log_level":"INFO","message":"订单ID 20240615001 支付成功,金额299.00元","user_id":1003,"ip_address":"192.168.1.150","response_time":120.3,"status_code":200,"is_success":true,"tags":["order","payment"],"request_body":"order_id=20240615001&amount=299.00","geo_location":{"lat":30.2741,"lon":120.1551},"request_count":1,"metadata":{"payment_gateway":"alipay","transaction_id":"txn_123456"},"create_time":"2024-06-15T08:40:15Z"}
{"index":{}}
{"timestamp":"2024-06-15 08:45:30","log_level":"DEBUG","message":"开始处理API请求 /api/v1/users/list","user_id":1004,"ip_address":"203.0.113.10","response_time":15.7,"status_code":200,"is_success":true,"tags":["api","debug"],"request_body":"page=1&size=20","geo_location":{"lat":22.3193,"lon":114.1694},"request_count":5,"metadata":{"endpoint":"/api/v1/users/list","method":"GET"},"create_time":"2024-06-15T08:45:30Z"}
{"index":{}}
{"timestamp":"2024-06-15 08:50:22","log_level":"ERROR","message":"文件上传失败:文件大小超过限制","user_id":1005,"ip_address":"192.168.1.200","response_time":320.8,"status_code":413,"is_success":false,"tags":["upload","file_size","error"],"request_body":"file=report.pdf","geo_location":{"lat":34.3416,"lon":108.9398},"request_count":2,"metadata":{"file_name":"report.pdf","file_size":"15MB","max_size":"10MB"},"create_time":"2024-06-15T08:50:22Z"}
{"index":{}}
{"timestamp":"2024-06-15 08:55:47","log_level":"INFO","message":"缓存刷新完成,共清理 1250 个过期条目","user_id":null,"ip_address":"10.0.1.100","response_time":45.0,"status_code":200,"is_success":true,"tags":["cache","cleanup"],"request_body":"action=refresh_cache","geo_location":{"lat":29.4316,"lon":106.9123},"request_count":1,"metadata":{"cache_type":"redis","cleaned_count":1250},"create_time":"2024-06-15T08:55:47Z"}
{"index":{}}
{"timestamp":"2024-06-15 09:00:12","log_level":"WARN","message":"API响应时间较慢,当前平均响应时间 850ms","user_id":null,"ip_address":"172.17.20.30","response_time":850.0,"status_code":200,"is_success":true,"tags":["performance","slow"],"request_body":"","geo_location":{"lat":36.0611,"lon":120.3783},"request_count":100,"metadata":{"avg_response_time":850,"threshold":500},"create_time":"2024-06-15T09:00:12Z"}
{"index":{}}
{"timestamp":"2024-06-15 09:05:33","log_level":"INFO","message":"用户李四修改个人资料信息","user_id":1006,"ip_address":"203.0.113.45","response_time":78.9,"status_code":200,"is_success":true,"tags":["profile","update"],"request_body":"name=李四&email=lisi@example.com","geo_location":{"lat":38.0428,"lon":114.5149},"request_count":1,"metadata":{"updated_fields":["name","email"]},"create_time":"2024-06-15T09:05:33Z"}
{"index":{}}
{"timestamp":"2024-06-15 09:10:18","log_level":"ERROR","message":"第三方服务调用失败:支付网关无响应","user_id":1007,"ip_address":"192.168.2.100","response_time":3000.2,"status_code":503,"is_success":false,"tags":["external_service","payment","timeout"],"request_body":"payment_data=encrypted","geo_location":{"lat":45.758,"lon":126.642},"request_count":3,"metadata":{"service_name":"payment-gateway","timeout_ms":5000},"create_time":"2024-06-15T09:10:18Z"}

在这里插入图片描述

5.1 数据验证查询

插入数据后,您可以使用以下查询验证:

1️⃣ 查看数据总数

GET /test-index/_count

在这里插入图片描述

2️⃣ 查看最新几条数据

GET /test-index/_search
{
  "size": 5,
  "sort": [
    {
      "timestamp": {
        "order": "desc"
      }
    }
  ]
}

在这里插入图片描述

3️⃣ 测试字段数据统计 - 按日志级别聚合

GET /test-index/_search
{
  "size": 0,
  "aggs": {
    "log_level_stats": {
      "terms": {
        "field": "log_level"
      }
    }
  }
}

在这里插入图片描述

4️⃣ 测试中文搜索

GET /test-index/_search
{
  "query": {
    "match": {
      "message": "用户登录"
    }
  }
}

在这里插入图片描述

5.2 数据特点说明

这些测试数据具有以下特点:

  • 覆盖所有字段类型:包含了映射中定义的所有字段类型
  • 中文内容message 字段包含丰富的中文文本
  • 多样化的日志级别:INFO、ERROR、WARN、DEBUG
  • 真实的地理位置:包含中国主要城市的经纬度
  • 不同的IP地址段:内网 IP、公网 IP
  • 多样的状态码:200、500、413、503
  • 丰富的标签:不同类型的业务标签
  • 完整的时间序列:按时间顺序排列的时间戳

这些数据非常适合测试搜索、聚合、排序等功能的完整性和性能。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大数据与AI实验室

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值