PHP Easysearch 2.0.0: Complete Guide to Connection FAQs and Solutions
This article walks through a full PHP project that demonstrates how to connect to Easysearch 2.0.0, covering client singleton setup, index mapping, CRUD operations, query optimization, and detailed troubleshooting steps for common connection, query, and sorting issues.
Project structure
The demo project easphpPrj follows a layered layout:
easphpPrj/
├── src/ # core code
│ ├── Entity/ # document models
│ ├── Manager/ # client manager (handles Easysearch 2.0.0 connection)
│ └── Repository/ # CRUD and query logic
├── tests/ # test scripts
├── .env # configuration file
└── composer.json # dependenciesTechnical stack:
PHP 7.4+
Easysearch 2.0.0 (target search engine) elasticsearch/elasticsearch – official PHP client for Elasticsearch (used to communicate with Easysearch)
PHPUnit – test runner
Client connection management
A singleton pattern ensures a single client instance. The connection URL is built with credentials, SSL verification can be disabled for self‑signed certificates, and reasonable timeouts are set.
// Build full URL with credentials
$hostUrl = $schema . '://' . $username . ':' . $password . '@' . $host . ':' . $port;
$clientBuilder->setHosts([$hostUrl]); // tell the client where Easysearch lives
// Disable SSL verification for self‑signed certs (development only)
$clientBuilder->setSSLVerification(false);
// Set timeout parameters (seconds)
$clientBuilder->setConnectionParams([
'client' => [
'timeout' => 30, // overall operation timeout
'connect_timeout' => 15 // connection establishment timeout
]
]);Index (mapping) design
Each index is analogous to a relational table. The mappings section defines field types and how they are indexed. Adding a .keyword sub‑field to text fields enables exact match and aggregation.
'mappings' => [
'properties' => [
'title' => [
'type' => 'text',
'analyzer' => 'standard',
'fields' => [
'keyword' => [
'type' => 'keyword',
'ignore_above' => 256
]
]
],
// ... other fields
]
]Document CRUD operations
Insert document
$document = new Document();
$document->setTitle('测试文档');
$document->setContent('这是一个测试文档');
$insertCount = $documentRepository->insert($document);Update document
By ID:
$document->setId($id);
$document->setTitle('更新后的标题');
$updateCount = $documentRepository->updateById($document);By condition:
$updateCount = $documentRepository->update($document, [
'term' => ['title' => '测试文档']
]);Delete document
$deleteCount = $documentRepository->delete([
'term' => ['title' => '测试文档']
]);Retrieval operations
Single‑document query:
$document = $documentRepository->one([
'term' => ['title' => '测试文档 1']
]);Multi‑document query (match):
$searchParams = [
'index' => $indexName,
'body' => [
'query' => [
'match' => [
'content' => 'Elasticsearch'
]
]
]
];
$searchResponse = $client->search($searchParams);Smart query fallback
If a term query fails, the code automatically falls back to a match query, improving success for fields that are tokenized.
$matchConditions = [];
foreach ($conditions as $key => $value) {
if (is_array($value)) {
foreach ($value as $field => $fieldValue) {
$matchConditions['match'][$field] = $fieldValue;
}
}
}Aggregation operations
Simple count
$countParams = [
'index' => $indexName,
'body' => [
'size' => 0,
'aggs' => [
'total_docs' => [
'value_count' => ['field' => 'title.keyword']
]
]
]
];
$countResponse = $client->search($countParams);
$totalDocs = $countResponse['aggregations']['total_docs']['value'];Complex group‑by (title prefix)
$prefixParams = [
'index' => $indexName,
'body' => [
'size' => 0,
'aggs' => [
'title_prefix' => [
'terms' => [
'field' => 'title.keyword',
'include' => '测试文档.*'
]
]
]
]
];Common issues & solutions
1. Connection problem – "No alive nodes found"
Symptom: client is created but any operation reports no alive nodes.
Root cause: network, service, authentication, or SSL misconfiguration prevents reaching Easysearch.
Network : ensure firewall allows port 9200/9201. Verify with telnet targetIP 9200.
Service : confirm Easysearch process is running. Access http://localhost:9200 in a browser to see cluster info.
Authentication : check .env for correct username and password.
SSL : if using HTTPS, disable verification in development with setSSLVerification(false) or provide a valid certificate.
2. Query issue – term on text returns empty
Symptom: exact phrase stored in a text field is not found with a term query.
Root cause: text fields are tokenized; the raw phrase does not match the token list.
Solution:
Use match for full‑text fields (tokenized search).
Use the .keyword sub‑field for exact matches with term or for aggregations.
3. Sorting issue – "No mapping found for [field.keyword]"
Symptom: sorting on title.keyword fails.
Root cause: the keyword sub‑field was not defined in the index mapping.
Solution:
Update the mapping to include fields => ['keyword' => ['type' => 'keyword']] for the target field.
Recreate the index and re‑import data.
Verify field names and spelling.
Key takeaways
Connection configuration is foundational : a singleton client with proper timeouts and SSL handling keeps the system stable.
Tokenization vs. keyword mapping : understanding text (tokenized) and keyword (exact) fields is essential for correct queries, aggregations, and sorting.
Proactive error handling : anticipating "No alive nodes" and tokenization pitfalls reduces debugging time.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Mingyi World Elasticsearch
The leading WeChat public account for Elasticsearch fundamentals, advanced topics, and hands‑on practice. Join us to dive deep into the ELK Stack (Elasticsearch, Logstash, Kibana, Beats).
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
