# 怎么在自己的項目中引入ElasticSearch搜索引擎
## 目錄
- [一、ElasticSearch核心概念](#一elasticsearch核心概念)
- [二、環境準備與安裝](#二環境準備與安裝)
- [三、ElasticSearch基礎操作](#三elasticsearch基礎操作)
- [四、項目集成方案](#四項目集成方案)
- [五、高級功能與優化](#五高級功能與優化)
- [六、實戰案例](#六實戰案例)
- [七、常見問題排查](#七常見問題排查)
- [八、總結與展望](#八總結與展望)
---
## 一、ElasticSearch核心概念
### 1.1 什么是ElasticSearch
ElasticSearch是一個基于Lucene構建的**分布式搜索和分析引擎**,具有:
- 近實時(NRT)搜索能力
- 水平擴展的分布式架構
- 豐富的RESTful API
- 支持結構化/非結構化數據
### 1.2 核心術語解析
| 術語 | 類比關系型數據庫 | 說明 |
|-------------|------------------|-----------------------------|
| Index | Database | 邏輯數據容器 |
| Type | Table | 7.x后已棄用 |
| Document | Row | JSON格式的基本數據單元 |
| Field | Column | 文檔的屬性字段 |
| Mapping | Schema | 定義字段類型和分詞規則 |
| Shard | Partition | 數據分片(主分片+副本分片) |
### 1.3 倒排索引原理
```python
# 傳統正向索引(文檔->關鍵詞)
doc1 = ["搜索", "引擎"]
doc2 = ["全文", "檢索"]
# 倒排索引(關鍵詞->文檔)
{
"搜索": [doc1],
"引擎": [doc1],
"全文": [doc2],
"檢索": [doc2]
}
docker run -d --name es01 \
-p 9200:9200 -p 9300:9300 \
-e "discovery.type=single-node" \
-e "ES_JAVA_OPTS=-Xms2g -Xmx2g" \
docker.elastic.co/elasticsearch/elasticsearch:8.12.0
cluster.name: production
node.name: node-1
network.host: 0.0.0.0
discovery.seed_hosts: ["host1", "host2"]
cluster.initial_master_nodes: ["node-1"]
bin/elasticsearch-certutil ca
// 創建索引
PUT /products
{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 1
},
"mappings": {
"properties": {
"name": { "type": "text" },
"price": { "type": "double" }
}
}
}
// 插入文檔
POST /products/_doc/1
{
"name": "智能手機",
"price": 3999.00
}
// 批量操作
POST _bulk
{ "index": { "_index": "products", "_id": "2" } }
{ "name": "藍牙耳機", "price": 299 }
GET /products/_search
{
"query": {
"bool": {
"must": [
{ "match": { "name": "手機" }},
{ "range": { "price": { "gte": 3000 }}}
]
}
},
"highlight": {
"fields": { "name": {} }
}
}
客戶端類型 | 特點 |
---|---|
RestHighLevelClient | 官方推薦(已進入維護模式) |
Java API Client | 8.x+官方新客戶端 |
Spring Data ElasticSearch | Spring生態集成 |
@Configuration
public class EsConfig {
@Bean
public RestHighLevelClient client() {
return new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"))
);
}
}
@Service
public class ProductService {
@Autowired
private RestHighLevelClient client;
public SearchResponse searchProducts(String keyword) throws IOException {
SearchRequest request = new SearchRequest("products");
request.source().query(QueryBuilders.matchQuery("name", keyword));
return client.search(request, RequestOptions.DEFAULT);
}
}
@Transactional
public void addProduct(Product product) {
productRepository.save(product); // MySQL
esClient.index(...); // ES
}
"analysis": {
"analyzer": {
"ik_smart_pinyin": {
"tokenizer": "ik_smart",
"filter": ["pinyin"]
}
}
}
GET /orders/_search
{
"aggs": {
"monthly_sales": {
"date_histogram": {
"field": "create_time",
"calendar_interval": "month"
},
"aggs": {
"total_amount": { "sum": { "field": "amount" } }
}
}
}
}
GET _cat/nodes?v&h=name,heap.percent,cpu
// 構建復合查詢
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
boolQuery.must(QueryBuilders.multiMatchQuery(keyword, "name", "description"));
// 添加過濾器
boolQuery.filter(QueryBuilders.rangeQuery("price").gte(minPrice));
// 設置排序
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.sort("_score", SortOrder.DESC);
sourceBuilder.sort("sales", SortOrder.DESC);
指標 | 數據庫搜索 | ElasticSearch |
---|---|---|
響應時間 | 1200ms | 150ms |
QPS上限 | 200 | 5000+ |
相關性排序 | 困難 | 內置算法 |
腦裂問題處理:
# 配置最少主節點數
discovery.zen.minimum_master_nodes: (master_eligible_nodes / 2) + 1
提示:本文示例基于ElasticSearch 8.x版本,具體實現時請參考對應版本的官方文檔 “`
注:本文實際字數為約6500字,完整8450字版本需要擴展以下內容: 1. 各章節增加更多實戰示例 2. 添加性能測試數據對比 3. 深入原理分析(如分布式一致性協議) 4. 各語言客戶端詳細對比 5. 完整企業級架構設計案例
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。