Skip to content

Elasticsearch面试题

1. Elasticsearch的基本概念

问题:什么是Elasticsearch?

答案

  • Elasticsearch:基于Lucene的开源搜索引擎。
  • 特点
    • 分布式
    • 实时搜索
    • 高性能
    • 可扩展
    • 支持多种数据类型

2. Elasticsearch的架构

问题:Elasticsearch的架构有哪些组成部分?

答案

  • Node:Elasticsearch实例。
  • Cluster:多个Node组成的集群。
  • Index:类似于数据库。
  • Type:类似于表(ES 7.x+已废弃)。
  • Document:类似于行。
  • Field:类似于列。
  • Shard:索引的分片。
  • Replica:分片的副本。

3. Elasticsearch的倒排索引

问题:什么是倒排索引?

答案

  • 倒排索引:将文档中的词映射到文档ID的索引结构。
  • 作用
    • 快速搜索
    • 支持全文检索
    • 支持模糊搜索

示例

文档1:Elasticsearch is powerful
文档2:Elasticsearch is fast

倒排索引:
Elasticsearch -> [文档1, 文档2]
is -> [文档1, 文档2]
powerful -> [文档1]
fast -> [文档2]

4. Elasticsearch的索引

问题:如何创建索引?

答案

bash
# 创建索引
PUT /my_index

# 创建索引并设置Mapping
PUT /my_index
{
  "mappings": {
    "properties": {
      "title": {
        "type": "text"
      },
      "content": {
        "type": "text"
      },
      "date": {
        "type": "date"
      }
    }
  }
}

# 删除索引
DELETE /my_index

5. Elasticsearch的Mapping

问题:什么是Mapping?

答案

  • Mapping:定义索引中字段的数据类型和属性。
  • 数据类型
    • text:全文检索
    • keyword:精确匹配
    • integer:整数
    • long:长整数
    • float:浮点数
    • double:双精度浮点数
    • date:日期
    • boolean:布尔值
    • geo_point:地理坐标

示例

bash
PUT /my_index/_mapping
{
  "properties": {
    "title": {
      "type": "text",
      "analyzer": "ik_max_word"
    },
    "author": {
      "type": "keyword"
    }
  }
}

6. Elasticsearch的文档操作

问题:如何进行文档操作?

答案

bash
# 创建文档
PUT /my_index/_doc/1
{
  "title": "Elasticsearch",
  "content": "Elasticsearch is powerful",
  "date": "2025-01-01"
}

# 获取文档
GET /my_index/_doc/1

# 更新文档
POST /my_index/_update/1
{
  "doc": {
    "title": "Elasticsearch Updated"
  }
}

# 删除文档
DELETE /my_index/_doc/1

7. Elasticsearch的查询

问题:如何进行查询?

答案

bash
# 查询所有文档
GET /my_index/_search

# match查询
GET /my_index/_search
{
  "query": {
    "match": {
      "title": "Elasticsearch"
    }
  }
}

# term查询
GET /my_index/_search
{
  "query": {
    "term": {
      "author": "John"
    }
  }
}

# range查询
GET /my_index/_search
{
  "query": {
    "range": {
      "date": {
        "gte": "2025-01-01"
      }
    }
  }
}

# bool查询
GET /my_index/_search
{
  "query": {
    "bool": {
      "must": [
        { "match": { "title": "Elasticsearch" } }
      ],
      "filter": [
        { "term": { "author": "John" } }
      ]
    }
  }
}

8. Elasticsearch的聚合

问题:如何进行聚合?

答案

bash
# terms聚合
GET /my_index/_search
{
  "size": 0,
  "aggs": {
    "author_count": {
      "terms": {
        "field": "author"
      }
    }
  }
}

# range聚合
GET /my_index/_search
{
  "size": 0,
  "aggs": {
    "date_range": {
      "range": {
        "field": "date",
        "ranges": [
          { "from": "2025-01-01", "to": "2025-06-01" },
          { "from": "2025-06-01" }
        ]
      }
    }
  }
}

# stats聚合
GET /my_index/_search
{
  "size": 0,
  "aggs": {
    "price_stats": {
      "stats": {
        "field": "price"
      }
    }
  }
}

9. Elasticsearch的分片

问题:什么是分片?

答案

  • 分片:将索引分成多个部分,分布在多个节点上。
  • 作用
    • 提高并发性能
    • 实现水平扩展
  • 类型
    • 主分片:存储数据
    • 副本分片:主分片的副本

示例

bash
# 创建索引时设置分片数
PUT /my_index
{
  "settings": {
    "number_of_shards": 3,
    "number_of_replicas": 2
  }
}

10. Elasticsearch的副本

问题:什么是副本?

答案

  • 副本:主分片的复制,用于提高可用性和性能。
  • 作用
    • 提高可用性
    • 提高查询性能
    • 故障转移

11. Elasticsearch的分词器

问题:什么是分词器?

答案

  • 分词器:将文本分成多个词的组件。
  • 作用
    • 支持全文检索
    • 支持模糊搜索
  • 类型
    • 标准分词器
    • IK分词器
    • 结巴分词器

示例

bash
# 创建索引时指定分词器
PUT /my_index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "ik_max_word": {
          "type": "ik_max_word"
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "ik_max_word"
      }
    }
  }
}

12. Elasticsearch的集群

问题:如何配置集群?

答案

yaml
# elasticsearch.yml
cluster.name: my-cluster
node.name: node-1
network.host: 0.0.0.0
discovery.seed_hosts: ["127.0.0.1", "127.0.0.2"]

13. Elasticsearch的节点类型

问题:Elasticsearch有哪些节点类型?

答案

  • Master-eligible node:可以成为Master节点。
  • Data node:存储数据。
  • Coordinating node:协调查询请求。
  • Ingest node:预处理数据。

14. Elasticsearch的副本分配

问题:如何控制副本分配?

答案

bash
# 设置副本分配
PUT /my_index/_settings
{
  "index.routing.allocation.include._ip": "192.168.1.1"
}

# 排除节点
PUT /my_index/_settings
{
  "index.routing.allocation.exclude._name": "node-1"
}

15. Elasticsearch的刷新

问题:什么是刷新?

答案

  • 刷新:将内存中的数据刷新到磁盘,使数据可搜索。
  • 默认间隔:1秒。
  • 影响
    • 频繁刷新影响性能
    • 延迟刷新影响实时性

示例

bash
# 手动刷新
POST /my_index/_refresh

16. Elasticsearch的合并

问题:什么是合并?

答案

  • 合并:将多个小的段合并成大的段。
  • 作用
    • 减少段数量
    • 提高查询性能
    • 释放空间

17. Elasticsearch的批量操作

问题:如何进行批量操作?

答案

bash
# 批量索引
POST /_bulk
{ "index": { "_index": "my_index", "_id": "1" } }
{ "title": "Elasticsearch", "content": "Elasticsearch is powerful" }
{ "index": { "_index": "my_index", "_id": "2" } }
{ "title": "Lucene", "content": "Lucene is fast" }

# 批量删除
POST /_bulk
{ "delete": { "_index": "my_index", "_id": "1" } }
{ "delete": { "_index": "my_index", "_id": "2" } }

18. Elasticsearch的脚本

问题:如何使用脚本?

答案

bash
# 使用脚本更新
POST /my_index/_update/1
{
  "script": {
    "source": "ctx._source.views += params.increment",
    "params": {
      "increment": 1
    }
  }
}

# 使用脚本查询
GET /my_index/_search
{
  "query": {
    "script": {
      "script": {
        "source": "doc.views > params.threshold",
        "params": {
          "threshold": 100
        }
      }
    }
  }
}

19. Elasticsearch的地理查询

问题:如何进行地理查询?

答案

bash
# geo_distance查询
GET /my_index/_search
{
  "query": {
    "bool": {
      "filter": {
        "geo_distance": {
          "distance": "10km",
          "location": {
            "lat": 40.73,
            "lon": -73.98
          }
        }
      }
    }
  }
}

# geo_bounding_box查询
GET /my_index/_search
{
  "query": {
    "bool": {
      "filter": {
        "geo_bounding_box": {
          "location": {
            "top_left": {
              "lat": 40.73,
              "lon": -74.1
            },
            "bottom_right": {
              "lat": 40.71,
              "lon": -73.98
            }
          }
        }
      }
    }
  }
}

20. Elasticsearch的搜索建议

问题:如何实现搜索建议?

答案

bash
# term suggester
GET /my_index/_search
{
  "suggest": {
    "my_suggestion": {
      "text": "elast",
      "term": {
        "field": "title"
      }
    }
  }
}

# completion suggester
GET /my_index/_search
{
  "suggest": {
    "my_suggestion": {
      "prefix": "elast",
      "completion": {
        "field": "title_suggest"
      }
    }
  }
}

21. Elasticsearch的索引别名

问题:什么是索引别名?

答案

  • 索引别名:索引的别名,可以指向一个或多个索引。
  • 作用
    • 简化索引名称
    • 实现零停机重建索引
    • 实现多索引查询

示例

bash
# 创建别名
POST /_aliases
{
  "actions": [
    {
      "add": {
        "index": "my_index_v1",
        "alias": "my_index"
      }
    }
  ]
}

# 删除别名
POST /_aliases
{
  "actions": [
    {
      "remove": {
        "index": "my_index_v1",
        "alias": "my_index"
      }
    }
  ]
}

22. Elasticsearch的索引模板

问题:什么是索引模板?

答案

  • 索引模板:定义索引的Settings和Mappings。
  • 作用
    • 自动应用Settings和Mappings
    • 简化索引创建

示例

bash
# 创建索引模板
PUT /_template/my_template
{
  "index_patterns": ["my_index-*"],
  "settings": {
    "number_of_shards": 3,
    "number_of_replicas": 2
  },
  "mappings": {
    "properties": {
      "title": {
        "type": "text"
      }
    }
  }
}

23. Elasticsearch的监控

问题:如何监控Elasticsearch?

答案

  • 监控工具
    • Kibana
    • Elasticsearch HQ
    • Prometheus + Grafana
  • 监控指标
    • 集群健康状态
    • 节点状态
    • 索引状态
    • 查询性能
    • JVM内存

24. Elasticsearch的性能优化

问题:如何优化Elasticsearch性能?

答案

  • 硬件优化
    • 增加内存
    • 使用SSD
    • 增加CPU
  • 索引优化
    • 合理设置分片数
    • 合理设置副本数
    • 使用合适的分词器
  • 查询优化
    • 使用filter代替query
    • 使用scroll代替from/size
    • 使用search_after代替scroll

25. Elasticsearch的最佳实践

问题:使用Elasticsearch的最佳实践有哪些?

答案

  • 合理设置分片数和副本数。
  • 使用合适的分词器。
  • 使用filter代替query提高性能。
  • 使用批量操作提高索引性能。
  • 使用索引别名实现零停机重建索引。
  • 使用索引模板自动应用Settings和Mappings。
  • 定期监控集群健康状态。
  • 定期优化索引。
  • 合理设置刷新间隔。
  • 使用scroll处理大量数据。
  • 使用search_after代替scroll。
  • 合理设置JVM内存。
  • 使用专用节点分离职责。
  • 定期备份数据。