本文目录导读:

在PHP项目中使用Elasticsearch,通常有以下几个步骤和注意事项:
安装Elasticsearch PHP客户端
推荐使用官方客户端库:
composer require elasticsearch/elasticsearch
基本连接配置
<?php
require 'vendor/autoload.php';
use Elastic\Elasticsearch\ClientBuilder;
// 创建客户端
$client = ClientBuilder::create()
->setHosts(['localhost:9200']) // 单节点
// 多节点
// ->setHosts(['localhost:9200', 'localhost:9201'])
->build();
带认证的连接
$client = ClientBuilder::create()
->setHosts(['https://localhost:9200'])
->setBasicAuthentication('username', 'password') // 基础认证
->setSSLVerification(false) // 跳过SSL验证(开发环境)
->build();
常用操作示例
索引管理
// 创建索引
$params = [
'index' => 'articles',
'body' => [
'settings' => [
'number_of_shards' => 3,
'number_of_replicas' => 2
],
'mappings' => [
'properties' => [
'title' => ['type' => 'text'],
'content' => ['type' => 'text'],
'author' => ['type' => 'keyword'],
'publish_date' => ['type' => 'date'],
'tags' => ['type' => 'keyword']
]
]
]
];
$response = $client->indices()->create($params);
// 检查索引是否存在
$exists = $client->indices()->exists(['index' => 'articles']);
// 删除索引
$client->indices()->delete(['index' => 'articles']);
文档增删改
// 添加/更新文档
$params = [
'index' => 'articles',
'id' => '1', // 可选,不指定则自动生成
'body' => [
'title' => 'Elasticsearch入门教程',
'content' => '本文介绍Elasticsearch的基本概念和使用方法...',
'author' => '张三',
'publish_date' => '2024-01-15',
'tags' => ['elasticsearch', '搜索引擎']
]
];
$response = $client->index($params);
// 批量导入
$params = ['body' => []];
for ($i = 1; $i <= 100; $i++) {
$params['body'][] = [
'index' => [
'_index' => 'articles',
'_id' => $i
]
];
$params['body'][] = [
'title' => "文章标题{$i}",
'content' => "文章内容{$i}..."
];
}
$responses = $client->bulk($params);
// 删除文档
$client->delete([
'index' => 'articles',
'id' => '1'
]);
搜索查询
// 基础搜索
$params = [
'index' => 'articles',
'body' => [
'query' => [
'match' => [
'title' => 'Elasticsearch'
]
],
'size' => 10, // 返回数量
'from' => 0 // 偏移量(分页)
]
];
$response = $client->search($params);
// 处理搜索结果
$hits = $response['hits']['hits'];
$total = $response['hits']['total']['value'];
foreach ($hits as $hit) {
echo "ID: " . $hit['_id'] . "\n";
echo "Score: " . $hit['_score'] . "\n";
echo "Title: " . $hit['_source']['title'] . "\n\n";
}
// 复杂查询
$params = [
'index' => 'articles',
'body' => [
'query' => [
'bool' => [
'must' => [
['match' => ['title' => 'PHP']],
['match' => ['content' => 'Elasticsearch']]
],
'filter' => [
['term' => ['author' => '张三']],
['range' => ['publish_date' => ['gte' => '2024-01-01']]]
]
]
],
'sort' => [
'publish_date' => ['order' => 'desc']
],
'aggs' => [
'by_author' => [
'terms' => ['field' => 'author']
]
]
]
];
$response = $client->search($params);
高级特性
聚合查询
$params = [
'index' => 'orders',
'body' => [
'size' => 0,
'aggs' => [
'total_sales' => [
'sum' => ['field' => 'amount']
],
'sales_by_category' => [
'terms' => ['field' => 'category'],
'aggs' => [
'avg_price' => ['avg' => ['field' => 'amount']]
]
]
]
]
];
高亮显示
$params = [
'index' => 'articles',
'body' => [
'query' => [
'match' => ['content' => 'Elasticsearch']
],
'highlight' => [
'fields' => [
'content' => [
'pre_tags' => ['<strong>'],
'post_tags' => ['</strong>']
]
]
]
]
];
最佳实践
连接池管理
// 使用连接池提高性能
$client = ClientBuilder::create()
->setHosts(['localhost:9200'])
->setConnectionPool('\Elasticsearch\ConnectionPool\StaticNoPingConnectionPool')
->setRetries(2)
->build();
日志记录
$logger = ClientBuilder::defaultLogger('path/to/logs/elasticsearch.log');
$client = ClientBuilder::create()
->setHosts(['localhost:9200'])
->setLogger($logger)
->build();
错误处理
use Elastic\Elasticsearch\Exception\ClientResponseException;
use Elastic\Elasticsearch\Exception\MissingParameterException;
use Elastic\Elasticsearch\Exception\ServerResponseException;
try {
$response = $client->search($params);
} catch (ClientResponseException $e) {
// 4xx错误
echo "请求错误: " . $e->getMessage();
} catch (ServerResponseException $e) {
// 5xx错误
echo "服务器错误: " . $e->getMessage();
} catch (MissingParameterException $e) {
echo "缺少参数: " . $e->getMessage();
}
实战项目结构建议
// ElasticsearchService.php
class ElasticsearchService
{
private $client;
public function __construct()
{
$this->client = ClientBuilder::create()
->setHosts([env('ELASTICSEARCH_HOST')])
->setBasicAuthentication(
env('ELASTICSEARCH_USER'),
env('ELASTICSEARCH_PASS')
)
->build();
}
// 文章搜索
public function searchArticles($keyword, $page = 1, $perPage = 10)
{
$params = [
'index' => 'articles',
'body' => [
'query' => [
'multi_match' => [
'query' => $keyword,
'fields' => ['title^3', 'content^2', 'tags']
]
],
'from' => ($page - 1) * $perPage,
'size' => $perPage,
'highlight' => [
'fields' => [
'title' => new \stdClass(),
'content' => new \stdClass()
]
]
]
];
return $this->client->search($params);
}
// 同步数据
public function syncArticle($article)
{
$params = [
'index' => 'articles',
'id' => $article['id'],
'body' => [
'title' => $article['title'],
'content' => strip_tags($article['content']),
'author' => $article['author'],
'publish_date' => $article['created_at'],
'tags' => $article['tags']
]
];
return $this->client->index($params);
}
}
注意事项
- 数据同步:需要建立可靠的同步机制(实时或定时)将MySQL/MongoDB数据同步到ES
- 索引策略:合理设计mapping,避免使用dynamic mapping
- 分词器:中文建议使用ik分词器
- 性能优化:批量操作时使用bulk API,避免频繁单条操作
- 安全:线上环境务必开启认证和SSL
常用命令工具
# 查看索引 curl -X GET 'localhost:9200/_cat/indices?v' # 查看索引映射 curl -X GET 'localhost:9200/articles/_mapping' # 查看索引设置 curl -X GET 'localhost:9200/articles/_settings'
这个流程基本涵盖了PHP项目中集成Elasticsearch的主要场景,根据实际需求可以进一步扩展和优化。