opensearch-project/opensearch-php
Official PHP client for OpenSearch. Provides a convenient, low-level API for indexing and searching documents, managing clusters and indices, and calling OpenSearch endpoints from Laravel or any PHP app. Supports modern PHP versions and common auth options.
## Getting Started
### Minimal Setup
1. **Installation**
```bash
composer require opensearch-project/opensearch-php
Basic Client Initialization
use OpenSearch\Client;
$client = Client::create([
'hosts' => ['https://localhost:9200'],
'auth' => ['username' => 'admin', 'password' => 'admin']
]);
First Use Case: Indexing a Document
$params = [
'index' => 'products',
'id' => '1',
'body' => ['name' => 'Laptop', 'price' => 999.99]
];
$response = $client->index($params);
Where to Look First
src/OpenSearch/Client.php for core functionality and src/OpenSearch/Transport/ for transport-layer details.tests/ for real-world usage patterns.$client->index([
'index' => 'users',
'body' => ['name' => 'John', 'email' => 'john@example.com']
]);
$client->update([
'index' => 'users',
'id' => '1',
'body' => ['doc' => ['email' => 'new@example.com']]
]);
$params = [
'body' => [
['index' => ['_index' => 'users', '_id' => '1']],
['create' => ['name' => 'Alice']],
['index' => ['_index' => 'users', '_id' => '2']],
['create' => ['name' => 'Bob']]
]
];
$client->bulk($params);
$response = $client->search([
'index' => 'products',
'body' => [
'query' => [
'match' => ['name' => 'laptop']
]
]
]);
$response = $client->search([
'index' => 'products',
'body' => [
'aggs' => [
'avg_price' => ['avg' => ['field' => 'price']]
]
]
]);
$client->indices()->create([
'index' => 'logs',
'body' => ['settings' => ['number_of_shards' => 3]]
]);
$client->indices()->delete(['index' => 'logs']);
$client->cluster()->health();
$client->cluster()->pendingTasks();
Service Provider Setup
// config/services.php
'opensearch' => [
'hosts' => env('OPENSEARCH_HOSTS', 'http://localhost:9200'),
'auth' => [
'username' => env('OPENSEARCH_USER'),
'password' => env('OPENSEARCH_PASS'),
],
],
Binding the Client
// app/Providers/AppServiceProvider.php
public function register()
{
$this->app->singleton(Client::class, function ($app) {
return Client::create($app['config']['services.opensearch']);
});
}
Usage in Controllers
use OpenSearch\Client;
public function search(Client $client)
{
$results = $client->search(['index' => 'products', 'body' => ['query' => ['match_all' => new \stdClass()]]]);
return response()->json($results);
}
Leverage the client’s query DSL support to build reusable search logic:
class ProductSearchQueryBuilder
{
public function buildMatchQuery(string $field, string $value): array
{
return ['query' => ['match' => [$field => $value]]];
}
public function buildBoolQuery(array $must, array $filter = []): array
{
return [
'query' => [
'bool' => [
'must' => $must,
'filter' => $filter
]
]
];
}
}
Authentication Issues
auth is configured correctly for secure clusters. Basic auth:
'auth' => ['username' => 'user', 'password' => 'pass']
OpenSearch\Transport\TransportBuilder with a custom Transport class.SSL/TLS Configuration
$client = Client::create([
'hosts' => ['https://localhost:9200'],
'ssl' => ['verify_peer' => false]
]);
'ssl' => ['cafile' => '/path/to/ca.pem']
Bulk Operation Errors
items array with success/failure status. Always check for errors:
$response = $client->bulk($params);
foreach ($response['items'] as $item) {
if (isset($item['index']['error'])) {
// Handle error
}
}
Rate Limiting
$client = Client::create([
'hosts' => ['https://localhost:9200'],
'retries' => 3,
'retry_on_status' => [502, 503, 504, 429]
]);
Index/Field Mapping Conflicts
indices()->getMapping() to inspect:
$mapping = $client->indices()->getMapping(['index' => 'products']);
Enable Debug Logging
Use the OpenSearch\Transport\TransportBuilder to enable debug output:
$client = Client::create([
'hosts' => ['https://localhost:9200'],
'transport' => function () {
return new \OpenSearch\Transport\TransportBuilder()
->setHosts(['https://localhost:9200'])
->setLogger(new \Monolog\Logger('opensearch', [
new \Monolog\Handler\StreamHandler('php://stderr', \Monolog\Logger::DEBUG)
]))
->build();
}
]);
Raw HTTP Responses Access raw responses for debugging:
$response = $client->search(['index' => 'products', 'body' => ['query' => ['match_all' => new \stdClass()]]]);
$rawResponse = $response->getRawResponse(); // For advanced debugging
Common HTTP Errors
Custom Transport Layer
Extend OpenSearch\Transport\Transport to integrate with custom HTTP clients (e.g., Guzzle middleware):
class CustomTransport extends \OpenSearch\Transport\Transport
{
public function __construct($hosts, array $options = [])
{
parent::__construct($hosts, $options);
$this->setClient(new \GuzzleHttp\Client([
'middleware' => [new \GuzzleHttp\Middleware::tap(function ($request) {
// Modify request
})]
]));
}
}
Query DSL Helpers Create helper classes to abstract complex queries:
class SearchHelper
{
public static function paginatedQuery(int $page = 1, int $perPage = 10): array
{
return [
'from' =>
How can I help you explore Laravel packages today?