PHP 客户端
OpenSearch PHP 客户端提供了一种更安全、更简便的方式来与您的 OpenSearch 集群交互。您无需通过浏览器使用 OpenSearch 并可能将数据暴露给公众,而是可以构建一个 OpenSearch 客户端来处理向集群发送请求。该客户端包含一个 API 库,可让您在集群上执行各种操作并返回标准响应体。
本入门指南介绍了如何连接到 OpenSearch、索引文档和运行查询。有关客户端源代码,请参阅 opensearch-php 仓库。
设置
要将客户端添加到您的项目,请使用 composer 进行安装
composer require opensearch-project/opensearch-php
要安装特定主版本的客户端,请运行以下命令
composer require opensearch-project/opensearch-php:<version>
然后在您的代码中从 composer 导入自动加载文件
require __DIR__ . '/vendor/autoload.php';
连接到 OpenSearch
使用 PSR 客户端连接到 OpenSearch。有关受支持的 PSR 客户端的信息,请参阅客户端工厂。有关使用 PSR 客户端进行基本身份验证的信息,请参阅使用 PSR 客户端进行基本身份验证。
连接到 Amazon OpenSearch 服务
有关连接到 Amazon OpenSearch Service 的信息,请参阅使用 PSR 客户端进行 IAM 身份验证。
创建索引
要创建具有自定义设置的 OpenSearch 索引,请使用以下代码
public function createIndex()
{
$this->client->indices()->create([
'index' => INDEX_NAME,
'body' => [
'settings' => [
'index' => [
'number_of_shards' => 4
]
]
]
]);
}
索引文档
您可以使用以下代码将文档索引到 OpenSearch 中
public function create()
{
$time = time();
$this->existingID = $time;
$this->deleteID = $time . '_uniq';
// Create a document passing the id
$this->client->create([
'id' => $time,
'index' => INDEX_NAME,
'body' => $this->getData($time)
]);
// Create a document passing the id
$this->client->create([
'id' => $this->deleteID,
'index' => INDEX_NAME,
'body' => $this->getData($time)
]);
// Create a document without passing the id (will be generated automatically)
$this->client->create([
'index' => INDEX_NAME,
'body' => $this->getData($time + 1)
]);
}
搜索文档
以下代码使用 multi_match
查询在标题和导演字段中搜索“miller”。它提高了“miller”出现在标题字段中的文档的权重。
public function search()
{
$docs = $this->client->search([
//index to search in or '_all' for all indices
'index' => INDEX_NAME,
'size' => 1000,
'body' => [
'query' => [
'prefix' => [
'name' => 'wrecking'
]
]
]
]);
var_dump($docs['hits']['total']['value'] > 0);
// Search for it
$docs = $this->client->search([
'index' => INDEX_NAME,
'body' => [
'size' => 5,
'query' => [
'multi_match' => [
'query' => 'miller',
'fields' => ['title^2', 'director']
]
]
]
]);
var_dump($docs['hits']['total']['value'] > 0);
}
删除文档
您可以使用以下代码删除文档
public function deleteByID()
{
$this->client->delete([
'id' => $this->deleteID,
'index' => INDEX_NAME,
]);
}
删除索引
您可以使用以下代码删除索引
public function deleteByIndex()
{
$this->client->indices()->delete([
'index' => INDEX_NAME
]);
}
示例程序
以下示例程序创建了一个客户端并执行各种 OpenSearch 操作
<?php
require __DIR__ . '/vendor/autoload.php';
define('INDEX_NAME', 'test_elastic_index_name2');
class MyOpenSearchClass
{
protected ?\OpenSearch\Client $client;
protected $existingID = 1668504743;
protected $deleteID = 1668504743;
protected $bulkIds = [];
public function __construct()
{
// Simple Setup
$this->client = (new \OpenSearch\GuzzleClientFactory())->create([
'base_uri' => 'https://:9200',
'auth' => ['admin', getenv('OPENSEARCH_PASSWORD')],
'verify' => false, // Disables SSL verification for local development.
]);
}
// Create an index with non-default settings.
public function createIndex()
{
$this->client->indices()->create([
'index' => INDEX_NAME,
'body' => [
'settings' => [
'index' => [
'number_of_shards' => 4
]
]
]
]);
}
public function info()
{
// Print OpenSearch version information on console.
var_dump($this->client->info());
}
// Create a document
public function create()
{
$time = time();
$this->existingID = $time;
$this->deleteID = $time . '_uniq';
// Create a document passing the id
$this->client->create([
'id' => $time,
'index' => INDEX_NAME,
'body' => $this->getData($time)
]);
// Create a document passing the id
$this->client->create([
'id' => $this->deleteID,
'index' => INDEX_NAME,
'body' => $this->getData($time)
]);
// Create a document without passing the id (will be generated automatically)
$this->client->create([
'index' => INDEX_NAME,
'body' => $this->getData($time + 1)
]);
//This should throw an exception because ID already exists
// $this->client->create([
// 'id' => $this->existingID,
// 'index' => INDEX_NAME,
// 'body' => $this->getData($this->existingID)
// ]);
}
public function update()
{
$this->client->update([
'id' => $this->existingID,
'index' => INDEX_NAME,
'body' => [
//data must be wrapped in 'doc' object
'doc' => ['name' => 'updated']
]
]);
}
public function bulk()
{
$bulkData = [];
$time = time();
for ($i = 0; $i < 20; $i++) {
$id = ($time + $i) . rand(10, 200);
$bulkData[] = [
'index' => [
'_index' => INDEX_NAME,
'_id' => $id,
]
];
$this->bulkIds[] = $id;
$bulkData[] = $this->getData($time + $i);
}
//will not throw exception! check $response for error
$response = $this->client->bulk([
//default index
'index' => INDEX_NAME,
'body' => $bulkData
]);
//give elastic a little time to create before update
sleep(2);
// bulk update
for ($i = 0; $i < 15; $i++) {
$bulkData[] = [
'update' => [
'_index' => INDEX_NAME,
'_id' => $this->bulkIds[$i],
]
];
$bulkData[] = [
'doc' => [
'name' => 'bulk updated'
]
];
}
//will not throw exception! check $response for error
$response = $this->client->bulk([
//default index
'index' => INDEX_NAME,
'body' => $bulkData
]);
}
public function deleteByQuery(string $query)
{
if ($query == '') {
return;
}
$this->client->deleteByQuery([
'index' => INDEX_NAME,
'q' => $query
]);
}
// Delete a single document
public function deleteByID()
{
$this->client->delete([
'id' => $this->deleteID,
'index' => INDEX_NAME,
]);
}
public function search()
{
$docs = $this->client->search([
//index to search in or '_all' for all indices
'index' => INDEX_NAME,
'size' => 1000,
'body' => [
'query' => [
'prefix' => [
'name' => 'wrecking'
]
]
]
]);
var_dump($docs['hits']['total']['value'] > 0);
// Search for it
$docs = $this->client->search([
'index' => INDEX_NAME,
'body' => [
'size' => 5,
'query' => [
'multi_match' => [
'query' => 'miller',
'fields' => ['title^2', 'director']
]
]
]
]);
var_dump($docs['hits']['total']['value'] > 0);
}
// Write queries in SQL
public function searchUsingSQL()
{
$docs = $this->client->sql()->query([
'query' => "SELECT * FROM " . INDEX_NAME . " WHERE name = 'wrecking'",
'format' => 'json'
]);
var_dump($docs['hits']['total']['value'] > 0);
}
public function getMultipleDocsByIDs()
{
$docs = $this->client->search([
//index to search in or '_all' for all indices
'index' => INDEX_NAME,
'body' => [
'query' => [
'ids' => [
'values' => $this->bulkIds
]
]
]
]);
var_dump($docs['hits']['total']['value'] > 0);
}
public function getOneByID()
{
$docs = $this->client->search([
//index to search in or '_all' for all indices
'index' => INDEX_NAME,
'size' => 1,
'body' => [
'query' => [
'bool' => [
'filter' => [
'term' => [
'_id' => $this->existingID
]
]
]
]
]
]);
var_dump($docs['hits']['total']['value'] > 0);
}
public function searchByPointInTime()
{
$result = $this->client->createPointInTime([
'index' => INDEX_NAME,
'keep_alive' => '10m'
]);
$pitId = $result['pit_id'];
// Get first page of results in Point-in-Time
$result = $this->client->search([
'body' => [
'pit' => [
'id' => $pitId,
'keep_alive' => '10m',
],
'size' => 10, // normally you would do 10000
'query' => [
'match_all' => (object)[]
],
'sort' => '_id',
]
]);
var_dump($result['hits']['total']['value'] > 0);
$last = end($result['hits']['hits']);
$lastSort = $last['sort'] ?? null;
// Get next page of results in Point-in-Time
$result = $this->client->search([
'body' => [
'pit' => [
'id' => $pitId,
'keep_alive' => '10m',
],
'search_after' => $lastSort,
'size' => 10, // normally you would do 10000
'query' => [
'match_all' => (object)[]
],
'sort' => '_id',
]
]);
var_dump($result['hits']['total']['value'] > 0);
// Close Point-in-Time
$result = $this->client->deletePointInTime([
'body' => [
'pit_id' => $pitId,
]
]);
var_dump($result['pits'][0]['successful']);
}
// Delete index
public function deleteByIndex()
{
$this->client->indices()->delete([
'index' => INDEX_NAME
]);
}
//simple data to index
public function getData($time = -1)
{
if ($time == -1) {
$time = time();
}
return [
'name' => date('c', $time) . " - i came in like a wrecking ball",
'time' => $time,
'date' => date('c', $time)
];
}
}
try {
$e = new MyOpenSearchClass();
$e->info();
$e->createIndex();
$e->create();
//give elastic a little time to create before update
sleep(2);
$e->update();
$e->bulk();
$e->getOneByID();
$e->getMultipleDocsByIDs();
$e->search();
$e->searchUsingSQL();
$e->searchByPointInTime();
$e->deleteByQuery('');
$e->deleteByID();
$e->deleteByIndex();
} catch (\Throwable $th) {
echo 'uncaught error ' . $th->getMessage() . "\n";
}