Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/phoenix-venture/elasticsearch-bundle
The bundle works like a bridge to integrate Elasticsearch in Symfony. It provides developer APIs and eco-system to work with Elasticsearch easily using dependency injection (DI).
https://github.com/phoenix-venture/elasticsearch-bundle
elasticsearch elasticsearch-php symfony symfony-bundle
Last synced: about 1 month ago
JSON representation
The bundle works like a bridge to integrate Elasticsearch in Symfony. It provides developer APIs and eco-system to work with Elasticsearch easily using dependency injection (DI).
- Host: GitHub
- URL: https://github.com/phoenix-venture/elasticsearch-bundle
- Owner: phoenix-venture
- License: mit
- Created: 2023-12-05T07:19:53.000Z (12 months ago)
- Default Branch: main
- Last Pushed: 2024-03-25T07:18:50.000Z (8 months ago)
- Last Synced: 2024-09-30T16:20:55.046Z (about 2 months ago)
- Topics: elasticsearch, elasticsearch-php, symfony, symfony-bundle
- Language: PHP
- Homepage:
- Size: 52.7 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# PhoenixElasticsearchBundle
The bundle works like a bridge to integrate Elasticsearch in Symfony. It provides developer APIs and eco-system to work with Elasticsearch easily using dependency injection (DI).
- [Features](#features)
- [Installation](#installation)
- [Usage](#usage)
- [Commands](#commands)
- [Server](#server-related-commands)
- [Index](#index-related-commands)
- [Document](#document-related-commands)
- [Todo](#todo)
- [Roadmap](#roadmap)
- [Core library](#core-library)## Features
- Server status and information
- Index management
- Document management## Installation
- Clone repository.
```sh
# https://github.com/hirenchhatbar/elasticsearch-bundle
git clone [email protected]:hirenchhatbar/elasticsearch-bundle.git vendor/phoenix/elasticsearch-bundle
```- Install dependencies.
```sh
# https://packagist.org/packages/elasticsearch/elasticsearch
composer require elasticsearch/elasticsearch
```
- Autoload bundle with composer.json.```php
// composer.json
"autoload": {
"psr-4": {
"App\\": "src/","Phoenix\\ElasticsearchBundle\\": "vendor/phoenix/elasticsearch-bundle/"
}
},
```- Dump autoload with composer
```sh
composer dump-autoload
```- Add new bundle in config/bundles.php.
```php
// config/bundles.php
return [
Phoenix\ElasticsearchBundle\PhoenixElasticsearchBundle::class => ['all' => true],
]
```## Usage
### Create index class and register it as service with 'es.index' tag:
```php
// vendor/phoenix/api-bundle/Elasticsearch/Index/LocationIndex.php*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Phoenix\ApiBundle\Elasticsearch\Index;use Phoenix\ElasticsearchBundle\Index\AbstractIndex;
use Phoenix\ApiBundle\Elasticsearch\Document\LocationDocument;/**
* Class LocationIndex
*
* @package Phoenix\ApiBundle\Index
* @author Hiren Chhatbar
*/
class LocationIndex extends AbstractIndex
{
/**
* Holds name.
*
* @var string
*/
public string $name = 'location';/**
* Constructor.
*
* @param LocationDocument $document
*/
public function __construct(LocationDocument $document)
{
$this->document = $document;
}/**
* {@inheritDoc}
*
* @see \Phoenix\ElasticsearchBundle\Index\AbstractIndex::settings()
*/
public function settings(): array
{
$settings = $this->defaultSettings();return $settings;
}/**
* {@inheritDoc}
*
* @see \Phoenix\ElasticsearchBundle\Index\AbstractIndex::mappings()
*/
public function mappings(): array
{
$defaultMappings = $this->defaultMappings();$mappings = [
'properties' => [
'parent' => [
'type' => 'integer',
],
'name' => [
'type' => 'keyword',
],
'path' => [
'type' => 'keyword',
],
'level' => [
'type' => 'integer',
],
'latitude' => [
'type' => 'float',
],
'longitude' => [
'type' => 'float',
],
'slug' => [
'type' => 'text',
],
'uuid' => [
'type' => 'text',
],
'lat_long' => [
'type' => 'geo_point',
],
]
];return \array_merge_recursive($defaultMappings, $mappings, $this->translationMapping());
}
}
``````yaml
# vendor/phoenix/api-bundle/Resources/config/services_elasticsearch.yamlPhoenix\ApiBundle\Elasticsearch\Index\LocationIndex:
arguments: ['@Phoenix\ApiBundle\Elasticsearch\Document\LocationDocument']
tags: ['es.index']
calls:
- [setPrefix, ['%pes.index_prefix%']]
```### Create document class and register it as service with 'es.document' tag:
```php
// vendor/phoenix/api-bundle/Elasticsearch/Document/LocationDocument.php*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Phoenix\ApiBundle\Elasticsearch\Document;use Phoenix\ElasticsearchBundle\Document\AbstractDocument;
use Doctrine\ORM\QueryBuilder;
use Phoenix\ApiBundle\Service\QueryService;
use App\Entity\Location;
use Phoenix\ApiBundle\EntityService\LocationService;/**
* Class LocationDocument
*
* @package Phoenix\ApiBundle\Document
* @author Hiren Chhatbar
*/
class LocationDocument extends AbstractDocument
{
/**
* Holds object of QueryService.
*
* @var QueryService
*/
protected QueryService $queryService;/**
* Holds object of LocationService.
*
* @var LocationService
*/
protected LocationService $locationService;/**
* Constructor.
*
* @param QueryService $queryService
* @param LocationService $locationService
*/
public function __construct(QueryService $queryService, LocationService $locationService)
{
$this->queryService = $queryService;$this->locationService = $locationService;
}/**
* {@inheritDoc}
*
* @see \Phoenix\ElasticsearchBundle\Document\DocumentInterface::get()
*/
public function get(int $id): array
{
$res = $this->queryService->select('location__find_one', ['id' => $id]);$row = \reset($res['rows']);
if ($row['latitude'] && $row['longitude']) {
$row['lat_long'] = sprintf('%s,%s', $row['latitude'], $row['longitude']);
}$resTrans = $this->queryService->select('location_translation__find_by_object', ['object' => $id]);
foreach ($resTrans['rows'] as $rowTrans) {
unset($rowTrans['id']);$row['translation'][] = $rowTrans;
$fullnameTrans = [
'locale' => $rowTrans['locale'],
'field' => 'fullname',
'content' => $this->locationService->hierarchyAsString($row['id'], $rowTrans['locale']),
];$row['translation'][] = $fullnameTrans;
}$row['parent'] = $row['parent_id'];
unset($row['parent_id']);
return $row;
}/**
* {@inheritDoc}
*
* @see \Phoenix\ElasticsearchBundle\Document\DocumentInterface::queryBuilder()
*/
public function queryBuilder(): QueryBuilder
{
$qb = $this->queryService->repository(Location::class)->createQueryBuilder('l');$qb->select('l.id');
return $qb;
}
}
``````yaml
# vendor/phoenix/api-bundle/Resources/config/services_elasticsearch.yamlPhoenix\ApiBundle\Elasticsearch\Document\LocationDocument:
arguments: ['@Phoenix\ApiBundle\Service\QueryService', '@Phoenix\ApiBundle\EntityService\LocationService']
tags: ['es.document']
```### Use DI (Dependancy Injection) and use Phoenix\ElasticsearchBundle\Service and its search method to execute search query:
```php
// vendor/phoenix/api-bundle/CrudManipulator/LocationAdminCrudManipulator.php*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/namespace Phoenix\ApiBundle\CrudManipulator;
use Phoenix\ElasticsearchBundle\Service\DocumentService;
use Phoenix\ApiBundle\Elasticsearch\Index\LocationIndex;
use Phoenix\ElasticsearchBundle\Utils\Pagination;
use Phoenix\ElasticsearchBundle\Utils\Util;/**
* Class LocationCrudManipulator
*
* @package Phoenix\ApiBundle\CrudManipulator
* @author Hiren Chhatbar
*/
class LocationAdminCrudManipulator extends AbstractCrudManipulator
{
/**
* Holds object of LocationIndex.
*
* @var LocationIndex
*/
protected LocationIndex $locationIndex;/**
* Holds object of DocumentService.
*
* @var DocumentService
*/
protected DocumentService $documentService;/**
* Holds object of Pagination.
*
* @var Pagination
*/
protected Pagination $pagination;/**
* Holds object of Util.
*
* @var Util
*/
protected Util $util;/**
* Constructor.
*
* @param LocationIndex $locationIndex
* @param DocumentService $documentService
* @param Pagination $pagination
*/
public function __construct(LocationIndex $locationIndex, DocumentService $documentService, Pagination $pagination, Util $util)
{
$this->locationIndex = $locationIndex;$this->documentService = $documentService;
$this->pagination = $pagination;
$this->util = $util;
}
/**
* Returns list.
*
* @param array $input
*
* @return array
*/
public function list(array $input): array
{
$ret = [];$limit = $input['limit'] ?? 30;
$offset = $input['offset'] ?? 0;$body = [];
if (isset($input['name'])) {
$body['query']['bool']['filter'][]['wildcard']['name'] = [
'value' => \sprintf('*%s*', $this->util->escape($input['name'])),
];
}if (isset($input['fullname'])) {
$body['query']['bool']['filter'][]['wildcard']['fullname'] = [
'value' => \sprintf('*%s*', \sprintf('*%s*', $this->util->escape($input['fullname']))),
];
}if (isset($input['parent'])) {
$location = $input['parent'];$body['query']['bool']['filter'][]['term']['parent'] = [
'value' => $location->getId(),
];
}if (isset($input['path'])) {
$body['query']['bool']['filter'][]['wildcard']['path'] = [
'value' => \sprintf('*%s*', \sprintf('%s*', $this->util->escape($input['path']))),
];
}if (isset($input['order_by']) && $input['order_by']) {
$fld = key($input['order_by']);$ord = $input['order_by'][$fld];
$body['sort'][] = [$fld => $ord];
}$res = $this->documentService->search(
$this->index->name(),
$body,
$offset,
$limit,
true
);$ret = \array_merge(
$this->pagination->info($res['hits']['total']['value'], $limit, $offset),
['rows' => \array_column($res['hits']['hits'], '_source')]
);return $ret;
}
}
```## Commands
### Server related commands
```php
// Pings server
php bin/console phoenix:elasticsearch:client ping// Displays server info
php bin/console phoenix:elasticsearch:client info
```### Index related commands
```php
// Creates index for location
php bin/console phoenix:elasticsearch:index --name=location create
``````php
// Deletes index of location
php bin/console phoenix:elasticsearch:index --name=location delete
``````php
// Checks whether index for location exists or not
php bin/console phoenix:elasticsearch:index --name=location exists
``````php
// Displays settings of index for location
php bin/console phoenix:elasticsearch:index --name=location settings
``````php
// Displays mappings of index for location
php bin/console phoenix:elasticsearch:index --name=location mappings
``````php
// Updates settings in index for location
php bin/console phoenix:elasticsearch:index --name=location update-settings
``````php
// Updates settings in index for location
php bin/console phoenix:elasticsearch:index --name=location update-mappings
```### Document related commands
```php
// Index single document of location of ID given
php bin/console phoenix:elasticsearch:document --index=location --id=10 sync-by-id
``````php
// Index all documents of location
php bin/console phoenix:elasticsearch:document --index=location sync
``````php
// Delete all documents of location
php bin/console phoenix:elasticsearch:document --index=location delete-all
``````php
// Delete single document of given ID of location
php bin/console phoenix:elasticsearch:document --index=location --id=10 delete-by-id
``````php
// Displays document of given ID of location
php bin/console phoenix:elasticsearch:document --index=location --id=10 get
```## Todo
- Autocomplete
## Roadmap
- Set bundle in packagist, make it composer friendly
- Index deletion - ask confirmation
- Pretty array with settings and mappings display on console
- Reindexing - https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-reindex.html
- Other APIs - https://www.elastic.co/guide/en/elasticsearch/reference/current/rest-apis.html
- Analyzer / tokenizer - https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis.html
- Aggregation
- Remove bundle and convert this into component## Core library
- https://packagist.org/packages/elasticsearch/elasticsearch