本客戶端旨在降低elasticsearch的上手難度,依賴于官方的客戶端插件elasticsearch/elasticsearch
。直接使用官方客戶端需要手動(dòng)構(gòu)建復(fù)雜的請(qǐng)求體,
稍微有一點(diǎn)錯(cuò)誤,操作結(jié)果就不對(duì)。所以單獨(dú)構(gòu)建一個(gè)依賴官方客戶端的插件,用戶只需要傳入關(guān)鍵字即可,后面增加了類似于關(guān)系型數(shù)據(jù)庫
的鏈?zhǔn)讲僮鞣椒ǎ闷饋砀唵我恍?。?dāng)然,本插件只能滿足一些常用的功能需求,較為復(fù)雜的需求仍然需要手動(dòng)構(gòu)建請(qǐng)求體,你可以使用本插件
直接調(diào)用官方客戶端的方法。
根據(jù)elasticsearch安全策略需求,若你安裝的elasticsearch8以下,請(qǐng)使用v1.0.9及以下版本,若你安裝的elasticsearch8及以上版本,請(qǐng)使用v1.1.0及以上版本。
composer require xiaosongshu/elasticsearch
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.17.7
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e "xpack.security.enabled=false" -e "xpack.security.http.ssl.enabled=false" elasticsearch:8.15.0
兼容elasticsearch v8.15.5版本,高版本需要使用賬號(hào)密碼,賬號(hào)為elastic
密碼為123456
端口號(hào)為9201
,可以根據(jù)自己的實(shí)際需求調(diào)整配置。
docker run -d --name my-es -p 9201:9200 -p 9301:9300 -e "discovery.type=single-node" -e "ELASTIC_PASSWORD=123456" -e "xpack.security.enabled=true" elasticsearch:8.15.5
如果是多個(gè)服務(wù)之間調(diào)用,可能需要?jiǎng)?chuàng)建網(wǎng)絡(luò)
# 創(chuàng)建默認(rèn)的網(wǎng)絡(luò)橋接
docker network create default_network
# 創(chuàng)建網(wǎng)絡(luò)
docker network create shared_network
# 將Elasticsearch容器加入網(wǎng)絡(luò)(假設(shè)容器名為my-es,根據(jù)實(shí)際修改)
docker network connect shared_network my-es
# 將PHP容器加入網(wǎng)絡(luò)(假設(shè)容器名為your_php_container_name,根據(jù)實(shí)際修改)
docker network connect shared_network your_php_container_name
參考 加入Ik分詞器的方法:https://blog.csdn.net/weixin_44364444/article/details/125758975
支持thinkPHP,laravel,webman等常用框架,需要?jiǎng)?chuàng)建配置文件elasticsearch.php ,放到config/目錄下。
配置內(nèi)容如下所示:
return [
/** 節(jié)點(diǎn)列表 */
'nodes' => ['127.0.0.1:9200'],
/** 用戶名 */
'username'=>'',
/** 密碼 */
'password'=>'',
];
實(shí)例化客戶端
$client = new \Xiaosongshu\Elasticsearch\ESClient();
<?php
require_once 'vendor/autoload.php';
/** 實(shí)例化客戶端 elasticsearch鏈?zhǔn)讲僮餮菔?*/
$client = new \Xiaosongshu\Elasticsearch\ESClient([
/** 節(jié)點(diǎn)列表 */
'nodes' => ['192.168.101.170:9200'],
/** 用戶名 */
'username' => '',
/** 密碼 */
'password' => '',
]);
/** 獲取表結(jié)構(gòu) */
$result = $client->getMap(['index']);
/** 刪除索引 */
$client->deleteIndex('index');
/** 如果不存在index索引,則創(chuàng)建index索引 */
if (!$client->IndexExists('index')) {
/** 創(chuàng)建索引 */
$client->createIndex('index', '_doc');
}
/** 創(chuàng)建表 */
$result = $client->createMappings('index', '_doc', [
'id' => ['type' => 'long',],
'title' => ['type' => 'text', "fielddata" => true,],
'content' => ['type' => 'text', 'fielddata' => true],
'create_time' => ['type' => 'text'],
'test_a' => ["type" => "integer"],
'test_b' => ["type" => "rank_feature", "positive_score_impact" => false],
'test_c' => ["type" => "rank_feature"],
'name' => ['type' => 'text', "fielddata" => true,],
'age' => ['type' => 'integer'],
'sex' => ['type' => 'integer'],
]);
/** 批量插入數(shù)據(jù)鏈?zhǔn)讲僮?*/
$result = $client->table('index', '_doc')->insertAll([
[
'id' => rand(1, 99999),
'title' => '天有不測(cè)風(fēng)云',
'content' => '月有陰晴圓缺',
'create_time' => date('Y-m-d H:i:s'),
'test_a' => rand(1, 10),
'test_b' => rand(1, 10),
'test_c' => rand(1, 10),
'name' => '張三',
'age' => 27,
'sex' => 1
]
]);
/** 調(diào)用elasticsearch原生方法 */
$params = [
'index' => 'my_index',
'type' =>"_doc",
'id' => "demo",
];
/** 使用原生方法統(tǒng)計(jì)滿足某條件的數(shù)據(jù) */
$result = $client->count($params);
/** 使用原生方法判斷是否存在某一條數(shù)據(jù) */
$result = $client->exists($params);
/** 查詢數(shù)據(jù)鏈?zhǔn)讲僮?*/
$result = $client
/** 設(shè)置表名 */
->table('index','_doc')
/** must限制條件 */
->where(['title','=','測(cè)試'])
/** whereIn查詢 */
->whereIn('age',[28])
/** whereNotIn查詢 */
->whereNotIn('age',[27,29])
/** should限制條件 當(dāng)must和should沖突的時(shí)候,must條件優(yōu)先 */
->orWhere(['test_a','>',8])
/** 排序 */
->orderBy('test_a','asc')
/** 分頁 */
->limit(0,10)
/** 篩選查詢字段 */
->select(['name','age'])
/** 按字段分組 */
->groupBy(['age','sex'])
/** 聚合查詢 */
->sum(['age'])
/** 執(zhí)行查詢操作 */
->getAll();
/** 聚合查詢鏈?zhǔn)讲僮?*/
$result = $client->table('index','_doc')->max(['age'])->getAll();
/** 獲取所有數(shù)據(jù) */
$result = $client->table('index','_doc')->getAll();
/** 根據(jù)條件更新所有數(shù)據(jù)鏈?zhǔn)讲僮?*/
$result = $client->table('index','_doc')->where(['test_a','>',2])->updateAll(['name'=>'陳圓圓']);
/** 根據(jù)條件刪除數(shù)據(jù)鏈?zhǔn)讲僮?*/
$result = $client->table('index','_doc')->where(['test_a','>',2])->deleteAll();
/** 獲取所有的index索引 */
$result = $client->getIndex(['index']);
/** 使用id更新數(shù)據(jù) */
$result = $client->table('index','_doc')->updateById('kmXADJEBegXAJ580Qqp6',['content'=>'今天你測(cè)試了嗎']);
/** 使用id 刪除數(shù)據(jù) */
$result = $client->table('index','_doc')->deleteByIds(['kmXADJEBegXAJ580Qqp6']);
/** 使用id查詢數(shù)據(jù) */
$result = $client->table('index','_doc')->findById('kmXADJEBegXAJ580Qqp6');
/** 使用id批量查詢 */
$result = $client->table('index','_doc')->getByIds(['kmXADJEBegXAJ580Qqp6']);
/** 添加腳本 */
$script = <<<eof
if (doc.containsKey('content') && doc['content'].size() != 0) {
return doc['content.raw'].value + '_' + '誰不說按家鄉(xiāng)好';
} else {
return '字段缺失'; // 或者返回其他適當(dāng)?shù)哪J(rèn)值
}
eof;
$result = $client->addScript('update_content',$script);
/** 添加腳本 */
$result = $client->addScript('update_content2',"(doc['content'].value)+'_'+'abcdefg'");
/** 獲取腳本內(nèi)容 */
$result = $client->getScript('update_content');
/** 使用腳本查詢 */
$result = $client->table('index','_doc')->withScript('update_content11')->getAll();
/** 刪除腳本*/
$result = $client->deleteScript('update_content');
/** 原生查詢 ,請(qǐng)根據(jù)es版本自行編寫原生查詢語句 */
$result = $client->table('index')->query([
'index'=>'index',
'body'=>[
'query'=>[
'match_all'=>new \stdClass(),
],
'_source'=>['title','content'],
],
'from'=>0,
'size'=>10,
]);
/** 打印處理 結(jié)果*/
print_r($result);
php ./vendor/bin/phpunit -c phpunit.xml
Problem 1
elasticsearch 版本8以上測(cè)試
安裝es服務(wù):
docker run -d --name my-es -p 9201:9200 -p 9301:9300 -e "discovery.type=single-node" -e "ELASTIC_PASSWORD=123456" -e "xpack.security.enabled=true" elasticsearch:8.15.5
測(cè)試demo.php內(nèi)容如下:
<?php
require_once 'vendor/autoload.php';
/** 實(shí)例化客戶端 elasticsearch鏈?zhǔn)讲僮餮菔?*/
$client = new \Xiaosongshu\Elasticsearch\ESClient(
[
'nodes' => [
"192.168.110.72:9201",
"127.0.0.1:9201",
],
'username' => 'elastic',
'password' => '123456',
'proxy' => [
'client' => [
'curl' => [
CURLOPT_PROXY => '', // 明確禁用代理
CURLOPT_PROXYUSERPWD => '', // 清除代理認(rèn)證
CURLOPT_NOPROXY => '*' // 對(duì)所有主機(jī)禁用代理
]
]
]
]
);
/** 如果不存在index索引,則創(chuàng)建index索引 */
if (!$client->IndexExists('index')) {
/** 創(chuàng)建索引 */
$client->createIndex('index', '_doc');
/** 創(chuàng)建表 */
$result = $client->createMappings('index', '_doc', [
'id' => ['type' => 'long',],
'title' => ['type' => 'text', "fielddata" => true,],
'content' => ['type' => 'text', 'fielddata' => true],
'create_time' => ['type' => 'text'],
'test_a' => ["type" => "integer"],
'test_b' => ["type" => "rank_feature", "positive_score_impact" => false],
'test_c' => ["type" => "rank_feature"],
'name' => ['type' => 'text', "fielddata" => true,],
'age' => ['type' => 'integer'],
'sex' => ['type' => 'integer'],
]);
}
/** 批量插入數(shù)據(jù)鏈?zhǔn)讲僮?*/
$result = $client->table('index', '_doc')->insertAll([
[
'id' => rand(1, 99999),
'title' => '天有不測(cè)風(fēng)云',
'content' => '月有陰晴圓缺',
'create_time' => date('Y-m-d H:i:s'),
'test_a' => rand(1, 10),
'test_b' => rand(1, 10),
'test_c' => rand(1, 10),
'name' => '張三',
'age' => 27,
'sex' => 1
]
]);
$result = $client->table('index', '_doc')->getAll();
print_r($result);
執(zhí)行命令打印測(cè)試結(jié)果
php demo.php
控制臺(tái)打印結(jié)果如下
PS D:\php\esLib> php .\demo.php
Array
(
[took] => 2
[timed_out] =>
[_shards] => Array
(
[total] => 1
[successful] => 1
[skipped] => 0
[failed] => 0
)
[hits] => Array
(
[total] => Array
(
[value] => 3
[relation] => eq
)
[max_score] => 1
[hits] => Array
(
[0] => Array
(
[_index] => index
[_id] => luQvu5gBNSYzMoPMWPh1
[_score] => 1
[_source] => Array
(
[id] => 85746
[title] => 天有不測(cè)風(fēng)云
[content] => 月有陰晴圓缺
[create_time] => 2025-08-18 11:18:18
[test_a] => 10
[test_b] => 9
[test_c] => 10
[name] => 張三
[age] => 27
[sex] => 1
)
)
[1] => Array
(
[_index] => index
[_id] => l-Qvu5gBNSYzMoPMbfiF
[_score] => 1
[_source] => Array
(
[id] => 47805
[title] => 天有不測(cè)風(fēng)云
[content] => 月有陰晴圓缺
[create_time] => 2025-08-18 11:18:24
[test_a] => 8
[test_b] => 5
[test_c] => 8
[name] => 張三
[age] => 27
[sex] => 1
)
)
[2] => Array
(
[_index] => index
[_id] => mOQvu5gBNSYzMoPMxfjX
[_score] => 1
[_source] => Array
(
[id] => 4797
[title] => 天有不測(cè)風(fēng)云
[content] => 月有陰晴圓缺
[test_a] => 6
[test_b] => 2
[test_c] => 8
[name] => 張三
[age] => 27
[sex] => 1
)
)
)
)
)
$client->query方法報(bào)錯(cuò)
改成這樣就行了
/** 查詢數(shù)據(jù)鏈?zhǔn)讲僮?*/
$result = $client
/** 設(shè)置表名 */
->table('index','_doc')
/** must限制條件 */
->where(['title','=','測(cè)試'])
/** whereIn查詢 */
->whereIn('age',[28])
/** whereNotIn查詢 */
->whereNotIn('age',[27,29])
/** should限制條件 當(dāng)must和should沖突的時(shí)候,must條件優(yōu)先 */
->orWhere(['test_a','>',8])
/** 排序 */
->orderBy('test_a','asc')
/** 分頁 */
->limit(0,10)
/** 篩選查詢字段 */
->select(['name','age'])
/** 按字段分組 */
->groupBy(['age','sex'])
/** 聚合查詢 */
->sum(['age'])
/** 執(zhí)行查詢操作 */
->getAll();
如果這種不滿足,那就寫原生吧
感謝分享!