ES 添加测试数据

往 ES 添加测试数据有几种常用方式,下面按从简单到实用的顺序介绍。

方法一:用 curl 直接写入单条数据

Elasticsearch 是 REST API,直接发 POST/PUT 请求即可。

bash
# 写入一条文档,指定索引名 test-index,类型 _doc,ID 为 1
curl -X POST "http://localhost:9200/test-index/_doc/1" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "张三",
    "age": 25,
    "city": "深圳",
    "create_time": "2024-01-01"
  }'

自动生成 ID(不指定 ID):

bash
curl -X POST "http://localhost:9200/test-index/_doc" \
  -H "Content-Type: application/json" \
  -d '{"name": "李四", "age": 30, "city": "北京"}'

方法二:用 _bulk 批量写入(推荐)

_bulk 接口一次可以写入多条,效率高得多。注意每一行末尾必须是换行,最后一行也要有换行。

bash
curl -X POST "http://localhost:9200/test-index/_bulk?pretty" \
  -H "Content-Type: application/json" \
  --data-binary '
{"index":{"_id":"1"}}
{"name":"张三","age":25,"city":"深圳","create_time":"2024-01-01"}
{"index":{"_id":"2"}}
{"name":"李四","age":30,"city":"北京","create_time":"2024-01-02"}
{"index":{"_id":"3"}}
{"name":"王五","age":28,"city":"上海","create_time":"2024-01-03"}
{"index":{"_id":"4"}}
{"name":"赵六","age":35,"city":"深圳","create_time":"2024-01-04"}
{"index":{"_id":"5"}}
{"name":"孙七","age":22,"city":"广州","create_time":"2024-01-05"}
'

方法三:先建索引再写入(可自定义 mapping)

如果要指定字段类型(比如 age 为 integer、create_time 为 date),先建索引:

bash
curl -X PUT "http://localhost:9200/test-index" \
  -H "Content-Type: application/json" \
  -d '{
    "mappings": {
      "properties": {
        "name":        { "type": "keyword" },
        "age":         { "type": "integer" },
        "city":        { "type": "keyword" },
        "create_time": { "type": "date" }
      }
    }
  }'

再执行上面的 _bulk 写入。

方法四:用 Kibana Dev Tools(可视化)

如果你有 Kibana,可以在 Dev Tools 控制台里写:

text
POST test-index/_doc
{
  "name": "张三",
  "age": 25,
  "city": "深圳"
}

批量用 _bulk,格式同上。

验证数据

bash
# 查看索引列表
curl "http://localhost:9200/_cat/indices?v"

# 查看文档总数
curl "http://localhost:9200/test-index/_count?pretty"

# 查询全部
curl "http://localhost:9200/test-index/_search?pretty"

# 条件查询:city 为深圳
curl -X POST "http://localhost:9200/test-index/_search?pretty" \
  -H "Content-Type: application/json" \
  -d '{
    "query": {
      "match": { "city": "深圳" }
    }
  }'

方法五:一条命令灌入大量假数据(脚本)

如果需要几万条测试数据,可以写个简单脚本:

bash
#!/bin/bash
# gen_data.sh:生成 1000 条测试数据并批量写入

URL="http://localhost:9200/test-index/_bulk"

# 先清空文件
> bulk_data.json

for i in $(seq 1 1000); do
  echo '{"index":{"_id":"'$i'"}}' >> bulk_data.json
  echo '{"name":"user_'$i'","age":'$((RANDOM % 60 + 18))',"city":"city_'$((RANDOM % 10))'"}' >> bulk_data.json
done

curl -X POST "$URL" \
  -H "Content-Type: application/json" \
  --data-binary @bulk_data.json

echo "写入完成"

执行:

bash
chmod +x gen_data.sh
./gen_data.sh

注意事项

  1. Content-Type 必须是 application/json,否则 ES 8.x 会报错。

  2. _bulk 的每一行末尾必须换行,包括最后一行,否则会解析失败。

  3. 索引名不要用大写字母,ES 会报 invalid_index_name_exception

  4. 删除测试索引(测试完想清掉):

    bash
    curl -X DELETE "http://localhost:9200/test-index"
  5. 如果是生产环境,写入前请确认索引名、mapping 和分片设置,避免影响其他数据。

最推荐先用方法三 + 方法二组合:先建好带 mapping 的索引,再用 _bulk 批量灌数据,既规范又高效。

 

原因分析

看你的输出:

text
health status index              pri rep docs.count ...
yellow open   test-index          1   1          6 ...
green  open   .apm-custom-link     1   0          0 ...
green  open   .kibana_task_manager_1  1   0      5 ...

关键在 pri rep 这两列:

  • pri = 1:主分片 1 个

  • rep = 1:副本分片 1 个

主分片分配成功了,所以数据能正常读写;但副本分片没地方分配,所以集群状态是 yellow

根本原因:单节点集群

你现在是 discovery.type: single-node 单节点部署。Elasticsearch 有一条铁律:

主分片和它的副本分片不能同时存在于同一个节点上。

因为副本的意义就是"主分片挂了,副本顶上",如果主副本在同一台机器上,机器一挂两个都没了,副本就失去了容灾意义。

方案一:把副本数设为 0(单节点开发环境推荐)

bash
curl -X PUT "http://localhost:9200/test-index/_settings" \
  -H "Content-Type: application/json" \
  -d '{
    "index": {
      "number_of_replicas": 0
    }
  }'

执行后再看:

bash
curl "http://localhost:9200/_cat/indices?v"

test-index 就会变成 green

以后新建索引默认也会带 1 个副本,可以在 elasticsearch.yml 里全局关闭:

yaml
index.number_of_replicas: 0

但这只影响之后自动创建的索引,已存在的索引还是要手动改。

 
posted @ 2026-09-13 14:59  Binky.Lee  阅读(5)  评论(0)    收藏  举报