Elasticsearch 快速参考:必备命令与技巧

用于搜索、索引和分析的 Elasticsearch 命令

目录

Elasticsearch 是一个基于 Apache Lucene 构建的强大分布式搜索和分析引擎。 这份全面的速查表涵盖了使用 Elasticsearch 集群时的基本命令、最佳实践和快速参考。

elasticsearch

注意:本指南中的大多数示例使用 cURL 进行 HTTP 请求。如果您是 cURL 的新手,或者需要高级选项的快速参考,请查看我们的 cURL 速查表,以获取详细的命令行 HTTP 请求技术。

集群管理

检查集群健康状况

本节中的所有命令都使用 cURL 与 Elasticsearch 的 REST API 进行交互。您可以根据需要自定义这些请求,添加额外的头部、身份验证和其他选项。

# 基本健康检查
curl -X GET "localhost:9200/_cluster/health?pretty"

# 带有分片信息的详细集群健康状况
curl -X GET "localhost:9200/_cluster/health?level=shards&pretty"

# 检查节点信息
curl -X GET "localhost:9200/_cat/nodes?v"

# 检查集群设置
curl -X GET "localhost:9200/_cluster/settings?pretty"

节点操作

# 列出所有节点
curl -X GET "localhost:9200/_cat/nodes?v&h=name,node.role,heap.percent,ram.percent,cpu,load_1m"

# 节点统计信息
curl -X GET "localhost:9200/_nodes/stats?pretty"

# 热线程(故障排除)
curl -X GET "localhost:9200/_nodes/hot_threads"

索引管理

创建和删除索引

# 创建索引
curl -X PUT "localhost:9200/my_index?pretty"

# 带有设置创建索引
curl -X PUT "localhost:9200/my_index" -H 'Content-Type: application/json' -d'
{
  "settings": {
    "number_of_shards": 3,
    "number_of_replicas": 1
  }
}
'

# 删除索引
curl -X DELETE "localhost:9200/my_index?pretty"

# 列出所有索引
curl -X GET "localhost:9200/_cat/indices?v"

# 索引统计信息
curl -X GET "localhost:9200/my_index/_stats?pretty"

索引映射

# 定义映射
curl -X PUT "localhost:9200/products" -H 'Content-Type: application/json' -d'
{
  "mappings": {
    "properties": {
      "name": { "type": "text" },
      "price": { "type": "float" },
      "created_at": { "type": "date" },
      "tags": { "type": "keyword" },
      "description": { 
        "type": "text",
        "analyzer": "english"
      }
    }
  }
}
'

# 获取映射
curl -X GET "localhost:9200/products/_mapping?pretty"

# 更新映射(添加字段)
curl -X PUT "localhost:9200/products/_mapping" -H 'Content-Type: application/json' -d'
{
  "properties": {
    "category": { "type": "keyword" }
  }
}
'

索引模板

# 创建索引模板
curl -X PUT "localhost:9200/_index_template/logs_template" -H 'Content-Type: application/json' -d'
{
  "index_patterns": ["logs-*"],
  "template": {
    "settings": {
      "number_of_shards": 1
    },
    "mappings": {
      "properties": {
        "timestamp": { "type": "date" },
        "message": { "type": "text" },
        "level": { "type": "keyword" }
      }
    }
  }
}
'

# 列出模板
curl -X GET "localhost:9200/_index_template?pretty"

文档操作(CRUD)

创建文档

# 使用自动生成的 ID 索引文档
curl -X POST "localhost:9200/products/_doc?pretty" -H 'Content-Type: application/json' -d'
{
  "name": "Laptop",
  "price": 999.99,
  "tags": ["electronics", "computers"]
}
'

# 使用特定 ID 索引文档
curl -X PUT "localhost:9200/products/_doc/1?pretty" -H 'Content-Type: application/json' -d'
{
  "name": "Laptop",
  "price": 999.99
}
'

# 批量索引
curl -X POST "localhost:9200/_bulk?pretty" -H 'Content-Type: application/json' -d'
{ "index": { "_index": "products", "_id": "1" }}
{ "name": "Laptop", "price": 999.99 }
{ "index": { "_index": "products", "_id": "2" }}
{ "name": "Mouse", "price": 29.99 }
'

读取文档

# 通过 ID 获取文档
curl -X GET "localhost:9200/products/_doc/1?pretty"

# 获取多个文档
curl -X GET "localhost:9200/_mget?pretty" -H 'Content-Type: application/json' -d'
{
  "docs": [
    { "_index": "products", "_id": "1" },
    { "_index": "products", "_id": "2" }
  ]
}
'

# 检查文档是否存在
curl -I "localhost:9200/products/_doc/1"

更新文档

# 更新文档
curl -X POST "localhost:9200/products/_update/1?pretty" -H 'Content-Type: application/json' -d'
{
  "doc": {
    "price": 899.99
  }
}
'

# 使用脚本更新
curl -X POST "localhost:9200/products/_update/1?pretty" -H 'Content-Type: application/json' -d'
{
  "script": {
    "source": "ctx._source.price *= params.discount",
    "params": {
      "discount": 0.9
    }
  }
}
'

# 更新或插入(upsert)
curl -X POST "localhost:9200/products/_update/1?pretty" -H 'Content-Type: application/json' -d'
{
  "doc": {
    "price": 899.99
  },
  "doc_as_upsert": true
}
'

删除文档

# 通过 ID 删除
curl -X DELETE "localhost:9200/products/_doc/1?pretty"

# 通过查询删除
curl -X POST "localhost:9200/products/_delete_by_query?pretty" -H 'Content-Type: application/json' -d'
{
  "query": {
    "match": {
      "name": "old"
    }
  }
}
'

搜索查询

基本搜索

# 匹配所有
curl -X GET "localhost:9200/products/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "query": {
    "match_all": {}
  }
}
'

# 匹配查询
curl -X GET "localhost:9200/products/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "query": {
    "match": {
      "name": "laptop"
    }
  }
}
'

# 多字段匹配查询
curl -X GET "localhost:9200/products/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "query": {
    "multi_match": {
      "query": "laptop gaming",
      "fields": ["name", "description"]
    }
  }
}
'

术语级查询

# 术语查询(精确匹配)
curl -X GET "localhost:9200/products/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "query": {
    "term": {
      "tags": "electronics"
    }
  }
}
'

# 多个值术语查询
curl -X GET "localhost:9200/products/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "query": {
    "terms": {
      "tags": ["electronics", "computers"]
    }
  }
}
'

# 范围查询
curl -X GET "localhost:9200/products/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "query": {
    "range": {
      "price": {
        "gte": 100,
        "lte": 1000
      }
    }
  }
}
'

# 存在查询
curl -X GET "localhost:9200/products/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "query": {
    "exists": {
      "field": "description"
    }
  }
}
'

布尔查询

# 布尔查询(must, should, must_not, filter)
curl -X GET "localhost:9200/products/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "query": {
    "bool": {
      "must": [
        { "match": { "name": "laptop" }}
      ],
      "filter": [
        { "range": { "price": { "gte": 500 }}}
      ],
      "should": [
        { "term": { "tags": "gaming" }}
      ],
      "must_not": [
        { "term": { "tags": "refurbished" }}
      ]
    }
  }
}
'

高级搜索

# 通配符查询
curl -X GET "localhost:9200/products/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "query": {
    "wildcard": {
      "name": "lap*"
    }
  }
}
'

# 模糊查询(容错拼写错误)
curl -X GET "localhost:9200/products/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "query": {
    "fuzzy": {
      "name": {
        "value": "laptpo",
        "fuzziness": "AUTO"
      }
    }
  }
}
'

# 前缀查询
curl -X GET "localhost:9200/products/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "query": {
    "prefix": {
      "name": "lap"
    }
  }
}
'

聚合

指标聚合

# 平均值、总和、最小值、最大值
curl -X GET "localhost:9200/products/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "size": 0,
  "aggs": {
    "avg_price": { "avg": { "field": "price" }},
    "max_price": { "max": { "field": "price" }},
    "min_price": { "min": { "field": "price" }},
    "total_sales": { "sum": { "field": "price" }}
  }
}
'

# 统计聚合
curl -X GET "localhost:9200/products/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "size": 0,
  "aggs": {
    "price_stats": {
      "stats": { "field": "price" }
    }
  }
}
'

桶聚合

# 术语聚合(按字段分组)
curl -X GET "localhost:9200/products/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "size": 0,
  "aggs": {
    "popular_tags": {
      "terms": {
        "field": "tags",
        "size": 10
      }
    }
  }
}
'

# 范围聚合
curl -X GET "localhost:9200/products/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "size": 0,
  "aggs": {
    "price_ranges": {
      "range": {
        "field": "price",
        "ranges": [
          { "to": 50 },
          { "from": 50, "to": 100 },
          { "from": 100 }
        ]
      }
    }
  }
}
'

# 日期直方图
curl -X GET "localhost:9200/logs/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "size": 0,
  "aggs": {
    "logs_over_time": {
      "date_histogram": {
        "field": "timestamp",
        "calendar_interval": "day"
      }
    }
  }
}
'

嵌套聚合

# 嵌套聚合
curl -X GET "localhost:9200/products/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "size": 0,
  "aggs": {
    "categories": {
      "terms": { "field": "category" },
      "aggs": {
        "avg_price": {
          "avg": { "field": "price" }
        }
      }
    }
  }
}
'

排序和分页

# 按字段排序
curl -X GET "localhost:9200/products/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "query": { "match_all": {} },
  "sort": [
    { "price": { "order": "desc" }},
    { "_score": { "order": "desc" }}
  ]
}
'

# 使用 from/size 分页
curl -X GET "localhost:9200/products/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "from": 0,
  "size": 10,
  "query": { "match_all": {} }
}
'

# 深度分页(search_after)
curl -X GET "localhost:9200/products/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "size": 10,
  "query": { "match_all": {} },
  "sort": [{ "price": "asc" }, { "_id": "asc" }],
  "search_after": [100, "product_123"]
}
'

字段选择和高亮

# 选择特定字段
curl -X GET "localhost:9200/products/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "query": { "match_all": {} },
  "_source": ["name", "price"]
}
'

# 高亮
curl -X GET "localhost:9200/products/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "query": {
    "match": { "description": "gaming laptop" }
  },
  "highlight": {
    "fields": {
      "description": {}
    }
  }
}
'

索引别名

# 创建别名
curl -X POST "localhost:9200/_aliases?pretty" -H 'Content-Type: application/json' -d'
{
  "actions": [
    { "add": { "index": "products_v1", "alias": "products" }}
  ]
}
'

# 将别名切换到新索引(零停机时间)
curl -X POST "localhost:9200/_aliases?pretty" -H 'Content-Type: application/json' -d'
{
  "actions": [
    { "remove": { "index": "products_v1", "alias": "products" }},
    { "add": { "index": "products_v2", "alias": "products" }}
  ]
}
'

# 列出别名
curl -X GET "localhost:9200/_cat/aliases?v"

重新索引

# 从一个索引重新索引到另一个索引
curl -X POST "localhost:9200/_reindex?pretty" -H 'Content-Type: application/json' -d'
{
  "source": {
    "index": "old_products"
  },
  "dest": {
    "index": "new_products"
  }
}
'

# 带查询重新索引
curl -X POST "localhost:9200/_reindex?pretty" -H 'Content-Type: application/json' -d'
{
  "source": {
    "index": "products",
    "query": {
      "range": {
        "price": { "gte": 100 }
      }
    }
  },
  "dest": {
    "index": "expensive_products"
  }
}
'

快照和备份

# 注册快照存储库
curl -X PUT "localhost:9200/_snapshot/my_backup?pretty" -H 'Content-Type: application/json' -d'
{
  "type": "fs",
  "settings": {
    "location": "/mount/backups/my_backup"
  }
}
'

# 创建快照
curl -X PUT "localhost:9200/_snapshot/my_backup/snapshot_1?wait_for_completion=true&pretty"

# 恢复快照
curl -X POST "localhost:9200/_snapshot/my_backup/snapshot_1/_restore?pretty"

# 列出快照
curl -X GET "localhost:9200/_snapshot/my_backup/_all?pretty"

# 删除快照
curl -X DELETE "localhost:9200/_snapshot/my_backup/snapshot_1?pretty"

性能优化

索引设置

# 批量索引期间禁用刷新
curl -X PUT "localhost:9200/products/_settings?pretty" -H 'Content-Type: application/json' -d'
{
  "index": {
    "refresh_interval": "-1"
  }
}
'

# 批量索引后重新启用
curl -X PUT "localhost:9200/products/_settings?pretty" -H 'Content-Type: application/json' -d'
{
  "index": {
    "refresh_interval": "1s"
  }
}
'

# 强制合并(优化)
curl -X POST "localhost:9200/products/_forcemerge?max_num_segments=1&pretty"

缓存清除

# 清除所有缓存
curl -X POST "localhost:9200/_cache/clear?pretty"

# 清除特定缓存
curl -X POST "localhost:9200/products/_cache/clear?query=true&pretty"

监控和故障排除

# 挂起任务
curl -X GET "localhost:9200/_cat/pending_tasks?v"

# 线程池统计信息
curl -X GET "localhost:9200/_cat/thread_pool?v"

# 段信息
curl -X GET "localhost:9200/_cat/segments?v"

# 恢复信息
curl -X GET "localhost:9200/_cat/recovery?v&h=index,stage,time"

# 任务 API
curl -X GET "localhost:9200/_tasks?detailed=true&pretty"

Python 客户端示例

from elasticsearch import Elasticsearch

# 连接到 Elasticsearch
es = Elasticsearch(['http://localhost:9200'])

# 索引文档
doc = {
    'name': 'Laptop',
    'price': 999.99,
    'tags': ['electronics']
}
es.index(index='products', id=1, document=doc)

# 搜索
resp = es.search(index='products', query={'match': {'name': 'laptop'}})
for hit in resp['hits']['hits']:
    print(hit['_source'])

# 批量索引
from elasticsearch.helpers import bulk

actions = [
    {
        '_index': 'products',
        '_id': i,
        '_source': {'name': f'Product {i}', 'price': i * 10}
    }
    for i in range(1000)
]
bulk(es, actions)

JavaScript/Node.js 客户端示例

Elasticsearch JavaScript 客户端提供了一种类型安全的方式来与您的集群进行交互。对于生产应用程序,建议使用 TypeScript 以获得更好的类型安全性和自动补全功能。请参阅我们的 TypeScript 速查表,以了解类型定义和接口的最佳实践。

const { Client } = require('@elastic/elasticsearch');
const client = new Client({ node: 'http://localhost:9200' });

// 索引文档
async function indexDoc() {
  await client.index({
    index: 'products',
    id: 1,
    document: {
      name: 'Laptop',
      price: 999.99
    }
  });
}

// 搜索
async function search() {
  const result = await client.search({
    index: 'products',
    query: {
      match: { name: 'laptop' }
    }
  });
  console.log(result.hits.hits);
}

// 批量索引
async function bulkIndex() {
  const operations = [];
  for (let i = 0; i < 1000; i++) {
    operations.push({ index: { _index: 'products', _id: i } });
    operations.push({ name: `Product ${i}`, price: i * 10 });
  }
  await client.bulk({ operations });
}

带强类型的 TypeScript 示例

import { Client } from '@elastic/elasticsearch';

interface Product {
  name: string;
  price: number;
  tags?: string[];
  created_at?: Date;
}

const client = new Client({ node: 'http://localhost:9200' });

async function indexProduct(product: Product, id: number): Promise<void> {
  await client.index<Product>({
    index: 'products',
    id: id.toString(),
    document: product
  });
}

async function searchProducts(query: string): Promise<Product[]> {
  const result = await client.search<Product>({
    index: 'products',
    query: {
      match: { name: query }
    }
  });
  
  return result.hits.hits.map(hit => hit._source as Product);
}

最佳实践

索引设计

  • 为了获得最佳性能,保持分片大小在 20-50GB 之间
  • 对于时间序列数据,使用索引生命周期管理(ILM)
  • 在索引数据之前仔细设计映射
  • 使用适当的字段类型(关键字 vs 文本,日期格式)
  • 如果不需要,禁用 _source 以减少大型文档的存储

查询优化

  • 当不需要评分时,使用过滤器而不是查询
  • 对于结构化数据,优先使用术语级查询
  • 使用 bool 查询高效地组合多个条件
  • 使用 search_after 实现深度分页
  • 缓存频繁使用的过滤器

索引性能

  • 使用批量 API 进行批量索引(每请求 1000-5000 个文档)
  • 批量操作期间禁用刷新
  • 重索引期间增加 index.refresh_interval
  • 使用多个线程/工作者进行并行索引
  • 考虑使用路由以获得更好的分片分布

集群管理

  • 定期监控集群健康状况
  • 设置适当的副本配置
  • 对于大型集群,使用专用主节点
  • 使用快照实施适当的备份策略
  • 监控 JVM 堆使用情况(保持在 75% 以下)

安全

  • 启用身份验证和授权(X-Pack 安全)
  • 生产部署中使用 HTTPS(配置 cURL 时使用 --cacert--cert--key 选项进行 SSL/TLS)
  • 实施适当的基于角色的访问控制
  • 定期进行安全更新和补丁
  • 加密静态和传输中的数据

常见用例

全文搜索

Elasticsearch 在全文搜索方面表现出色,具有以下功能:

  • 相关性评分
  • 模糊匹配
  • 短语匹配
  • 同义词处理
  • 多语言支持

日志分析(ELK 堆栈)

  • 使用 Logstash/Filebeat 收集日志
  • 在 Elasticsearch 中索引和搜索日志
  • 使用 Kibana 仪表板进行可视化
  • 设置异常警报

电子商务搜索

  • 产品目录搜索
  • 使用聚合进行面向的导航
  • 自动完成和建议
  • 个性化搜索结果

应用程序性能监控

  • 索引应用程序指标
  • 实时监控仪表板
  • 异常检测
  • 性能趋势分析

有用链接

官方 Elasticsearch 资源

相关速查表和指南