Search engines¶
Kinetis supports OpenSearch and Elasticsearch through separate packages.
Install the package for the engine you run; it also installs the shared
kinetis/search contract:
composer require kinetis/search-opensearch
# or: composer require kinetis/search-elasticsearch
The package binds its engine client and Kinetis\Search\SearchClient
when its host is configured. Use Search (OpenSearch) for OpenSearch
and Amazon OpenSearch Service, or Search (Elasticsearch) for
Elasticsearch and Elastic Cloud. Each guide covers authentication and
engine-specific setup.
Connect¶
Configure one origin for the installed engine:
SEARCH_OPENSEARCH_HOST=https://search.internal:9200
SEARCH_OPENSEARCH_USERNAME=app
SEARCH_OPENSEARCH_PASSWORD=secret
For Elasticsearch, use SEARCH_ELASTICSEARCH_HOST, ..._USERNAME and
..._PASSWORD instead. Both packages also accept ..._TIMEOUT (default
30 seconds), ..._MAX_RESPONSE_BYTES (default 8 MiB) and
..._VERIFY_PEER (default true). Put a load balancer in front of a
cluster: the client connects to one origin and does not select another
node after a failure. An http:// origin needs ..._PLAINTEXT=true;
use HTTPS when credentials or documents cross an untrusted network.
The host is required. Without it the package leaves its bindings unset. The package validates configuration when the application boots, without opening a connection. Configuration lists the keys, and Configuring has the complete origin, TLS and deadline contract.
Index and search¶
Inject the common interface to index a document and search either engine:
use Kinetis\Search\SearchClient;
final readonly class Articles
{
public function __construct(private SearchClient $search) {}
public function publish(string $id, array $article): void
{
$this->search->index('articles', $id, $article);
}
public function find(string $term): array
{
$result = $this->search->search('articles', [
'query' => ['match' => ['title' => $term]],
]);
return array_column($result['hits']['hits'], '_source');
}
}
Create the articles index and its mapping in your search engine before
using it in production. SearchClient also has get(), delete() and
bulk(). get() returns null when a document is absent; bulk() can
return HTTP 200 while individual writes failed, so check its errors
flag and items. A write with refresh: true is visible to search
before the call returns, at the cost of a refresh; use it only where
read-after-write matters. One client for either engine has the full
call and result contract.
The search body is the engine’s own query DSL. For index management,
mappings and engine-specific queries, inject the package’s concrete
OpenSearch\Client or Elastic\Elasticsearch\Client and use that
engine’s API. The common interface does not translate query languages.
When a request fails¶
SearchRequestException means the cluster answered with an error
status; inspect its status. SearchNetworkException means no complete
response arrived. After a failed index or bulk call, the write may have
reached the engine. Check the indexed document or use an idempotent
document ID before repeating it. The clients do not replay a failed
request automatically. The full failure contract is in
Failures.
More than one engine or connection¶
If both engine packages are installed, both bind SearchClient; the
last package bootstrap wins. Choose the binding explicitly in
bootstrap.php (Bootstrapping). Build a second named connection
with the engine factory and scoped keys described in
Named connections.
See also¶
Search (OpenSearch) and Search (Elasticsearch) — setup for each engine.
Appendix: Search contracts — configuration, client and transport contracts.
Telemetry — tracing search calls.