Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p

# Release Notes

## [Unreleased](https://github.com/algolia/search-bundle/compare/8.0.0...master)

## [v8.0.0](https://github.com/algolia/search-bundle/compare/7.0.0...8.0.0)

### Added
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"prefer-stable": true,
"require": {
"php": ">= 8.2",
"algolia/algoliasearch-client-php": "^3.0",
"algolia/algoliasearch-client-php": "^4.41.0",
"doctrine/event-manager": "^1.1 || ^2.0",
"doctrine/persistence": "^2.1 || ^3.0 || ^4.0",
"symfony/filesystem": "^7.0 || ^8.0",
Expand Down
6 changes: 3 additions & 3 deletions src/AlgoliaSearchBundle.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Algolia\SearchBundle;

use Algolia\AlgoliaSearch\Support\UserAgent;
use Algolia\AlgoliaSearch\Support\AlgoliaAgent;
use Symfony\Component\HttpKernel\Bundle\Bundle;
use Symfony\Component\HttpKernel\Kernel as SfKernel;

Expand All @@ -17,7 +17,7 @@ public function boot(): void
{
parent::boot();

UserAgent::addCustomUserAgent('Symfony Search Bundle', self::VERSION);
UserAgent::addCustomUserAgent('Symfony', SfKernel::VERSION);
AlgoliaAgent::addAlgoliaAgent('Search', 'Symfony Search Bundle', self::VERSION);
AlgoliaAgent::addAlgoliaAgent('Search', 'Symfony', SfKernel::VERSION);
}
}
4 changes: 2 additions & 2 deletions src/Command/SearchClearCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Algolia\SearchBundle\Command;

use Algolia\AlgoliaSearch\Response\IndexingResponse;
use Algolia\SearchBundle\Responses\NullResponse;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
Expand Down Expand Up @@ -34,7 +34,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
foreach ($indexToClear as $indexName => $className) {
$success = $this->searchService->clear($className);

if ($success instanceof IndexingResponse) {
if (!$success instanceof NullResponse) {
$output->writeln('Cleared <info>' . $indexName . '</info> index of <comment>' . $className . '</comment> ');
} else {
$output->writeln('<error>Index <info>' . $indexName . '</info> couldn\'t be cleared</error>');
Expand Down
22 changes: 16 additions & 6 deletions src/Command/SearchImportCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Algolia\SearchBundle\Command;

use Algolia\AlgoliaSearch\SearchClient;
use Algolia\AlgoliaSearch\Api\SearchClient;
use Algolia\SearchBundle\Entity\Aggregator;
use Algolia\SearchBundle\SearchService;
use Doctrine\Persistence\ManagerRegistry;
Expand Down Expand Up @@ -81,7 +81,12 @@ protected function execute(InputInterface $input, OutputInterface $output): int
if ($shouldDoAtomicReindex) {
$temporaryIndexName = $this->searchServiceForAtomicReindex->searchableAs($entityClassName);
$output->writeln("Creating temporary index <info>$temporaryIndexName</info>");
$this->searchClient->copyIndex($sourceIndexName, $temporaryIndexName, ['scope' => ['settings', 'synonyms', 'rules']]);
$copyResponse = $this->searchClient->operationIndex($sourceIndexName, [
'operation' => 'copy',
'destination' => $temporaryIndexName,
'scope' => ['settings', 'synonyms', 'rules'],
]);
$this->searchClient->waitForTask($sourceIndexName, $copyResponse['taskID']);
}

$allResponses = [];
Expand Down Expand Up @@ -119,13 +124,16 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$manager->clear();
}

if ($shouldDoAtomicReindex && isset($indexName)) {
if ($shouldDoAtomicReindex) {
$output->writeln("Waiting for indexing tasks to finalize\n");
foreach ($allResponses as $response) {
$response->wait();
}
$output->writeln("Moving <info>$indexName</info> -> <comment>$sourceIndexName</comment>\n");
$this->searchClient->moveIndex($indexName, $sourceIndexName);
$output->writeln("Moving <info>$temporaryIndexName</info> -> <comment>$sourceIndexName</comment>\n");
$this->searchClient->operationIndex($temporaryIndexName, [
'operation' => 'move',
'destination' => $sourceIndexName,
]);
}
}

Expand All @@ -149,7 +157,9 @@ private function formatIndexingResponse($batch)
$formattedResponse[$indexName] = 0;
}

$formattedResponse[$indexName] += count($apiResponse->current()['objectIDs']);
foreach ($apiResponse as $batchResponse) {
$formattedResponse[$indexName] += count($batchResponse['objectIDs']);
}
}
}

Expand Down
80 changes: 51 additions & 29 deletions src/Engine.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

namespace Algolia\SearchBundle;

use Algolia\AlgoliaSearch\Api\SearchClient;
use Algolia\AlgoliaSearch\RequestOptions\RequestOptions;
use Algolia\AlgoliaSearch\Response\BatchIndexingResponse;
use Algolia\AlgoliaSearch\Response\NullResponse;
use Algolia\AlgoliaSearch\SearchClient;
use Algolia\SearchBundle\Responses\EngineResponse;
use Algolia\SearchBundle\Responses\NullResponse;

/**
* @internal
Expand All @@ -20,6 +20,14 @@ public function __construct(SearchClient $client)
$this->client = $client;
}

/**
* @return SearchClient
*/
public function getClient()
{
return $this->client;
}

/**
* Add new objects to an index.
*
Expand All @@ -29,7 +37,7 @@ public function __construct(SearchClient $client)
* @param array<int, SearchableEntity> $searchableEntities
* @param array<string, int|string|array>|RequestOptions $requestOptions
*
* @return array<string, BatchIndexingResponse>
* @return array<string, array>
*
* @throws \Algolia\AlgoliaSearch\Exceptions\AlgoliaException
*/
Expand Down Expand Up @@ -59,13 +67,8 @@ public function index($searchableEntities, $requestOptions)
}

$result = [];
if (!array_key_exists('autoGenerateObjectIDIfNotExist', $requestOptions)) {
$requestOptions['autoGenerateObjectIDIfNotExist'] = true;
}
foreach ($data as $indexName => $objects) {
$result[$indexName] = $this->client
->initIndex($indexName)
->saveObjects($objects, $requestOptions);
$result[$indexName] = $this->client->saveObjects($indexName, $objects, false, 1000, $requestOptions);
}

return $result;
Expand All @@ -79,7 +82,7 @@ public function index($searchableEntities, $requestOptions)
* @param array<int, SearchableEntity> $searchableEntities
* @param array<string, int|string|array>|RequestOptions $requestOptions
*
* @return array<string, BatchIndexingResponse>
* @return array<string, array>
*
* @throws \Algolia\AlgoliaSearch\Exceptions\AlgoliaException
*/
Expand All @@ -106,9 +109,7 @@ public function remove($searchableEntities, $requestOptions)

$result = [];
foreach ($data as $indexName => $objects) {
$result[$indexName] = $this->client
->initIndex($indexName)
->deleteObjects($objects, $requestOptions);
$result[$indexName] = $this->client->deleteObjects($indexName, $objects, false, 1000, $requestOptions);
}

return $result;
Expand All @@ -117,23 +118,21 @@ public function remove($searchableEntities, $requestOptions)
/**
* Clear the records of an index without affecting its settings.
*
* This method enables you to delete an indexs contents (records) without
* This method enables you to delete an index's contents (records) without
* removing any settings, rules and synonyms.
*
* If you want to remove the entire index and not just its records, use the
* delete method instead.
*
* @param string $indexName
* @param array<string, int|string|array>|RequestOptions $requestOptions
*
* @return \Algolia\AlgoliaSearch\Response\AbstractResponse
*/
public function clear($indexName, $requestOptions)
{
$index = $this->client->initIndex($indexName);
if ($this->client->indexExists($indexName)) {
$response = $this->client->clearObjects($indexName, $requestOptions);

if ($index->exists($requestOptions)) {
return $index->clearObjects($requestOptions);
return new EngineResponse($this->client, $indexName, $response['taskID']);
}

return new NullResponse();
Expand All @@ -146,19 +145,17 @@ public function clear($indexName, $requestOptions)
* removes its metadata and configured settings (like searchable attributes or custom ranking).
*
* If the index has replicas, they will be preserved but will no longer be
* linked to their primary index. Instead, theyll become independent indices.
* linked to their primary index. Instead, they'll become independent indices.
*
* @param string $indexName
* @param array<string, int|string|array>|RequestOptions $requestOptions
*
* @return \Algolia\AlgoliaSearch\Response\AbstractResponse
*/
public function delete($indexName, $requestOptions)
{
$index = $this->client->initIndex($indexName);
if ($this->client->indexExists($indexName)) {
$response = $this->client->deleteIndex($indexName, $requestOptions);

if ($index->exists($requestOptions)) {
return $index->delete($requestOptions);
return new EngineResponse($this->client, $indexName, $response['taskID']);
}

return new NullResponse();
Expand All @@ -177,7 +174,27 @@ public function delete($indexName, $requestOptions)
*/
public function search($query, $indexName, $requestOptions)
{
return $this->client->initIndex($indexName)->search($query, $requestOptions);
$searchParams = ['query' => $query];
$httpOptions = [];

if ($requestOptions instanceof RequestOptions) {
$searchParams = array_merge($searchParams, $requestOptions->getBody());
$requestOptions = clone $requestOptions;
$requestOptions->setBody([]);

return $this->client->searchSingleIndex($indexName, $searchParams, $requestOptions);
}

$httpOptionKeys = ['headers', 'queryParameters', 'body', 'readTimeout', 'writeTimeout', 'connectTimeout'];
foreach ($requestOptions as $key => $value) {
if (in_array($key, $httpOptionKeys, true)) {
$httpOptions[$key] = $value;
} else {
$searchParams[$key] = $value;
}
}

return $this->client->searchSingleIndex($indexName, $searchParams, $httpOptions);
}

/**
Expand All @@ -195,7 +212,12 @@ public function searchIds($query, $indexName, $requestOptions)
{
$result = $this->search($query, $indexName, $requestOptions);

return array_column($result['hits'], 'objectID');
$ids = [];
foreach ($result['hits'] as $hit) {
$ids[] = $hit['objectID'];
}

return $ids;
}

/**
Expand All @@ -211,7 +233,7 @@ public function searchIds($query, $indexName, $requestOptions)
*/
public function count($query, $indexName, $requestOptions)
{
$results = $this->client->initIndex($indexName)->search($query, $requestOptions);
$results = $this->search($query, $indexName, $requestOptions);

return (int) $results['nbHits'];
}
Expand Down
6 changes: 3 additions & 3 deletions src/Resources/config/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@ services:
- { name: doctrine_mongodb.odm.event_subscriber }

search.client:
class: Algolia\AlgoliaSearch\SearchClient
class: Algolia\AlgoliaSearch\Api\SearchClient
public: true
lazy: true
factory: ['Algolia\AlgoliaSearch\SearchClient', 'create']
factory: ['Algolia\AlgoliaSearch\Api\SearchClient', 'create']
arguments:
$appId: '%env(ALGOLIA_APP_ID)%'
$apiKey: '%env(ALGOLIA_API_KEY)%'

Algolia\AlgoliaSearch\SearchClient:
Algolia\AlgoliaSearch\Api\SearchClient:
alias: search.client

Algolia\SearchBundle\SearchService:
Expand Down
32 changes: 32 additions & 0 deletions src/Responses/EngineResponse.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

namespace Algolia\SearchBundle\Responses;

use Algolia\AlgoliaSearch\Api\SearchClient;

/**
* @internal
*/
final class EngineResponse
{
/** @var SearchClient */
private $client;

/** @var string */
private $indexName;

/** @var int */
private $taskID;

public function __construct(SearchClient $client, string $indexName, int $taskID)
{
$this->client = $client;
$this->indexName = $indexName;
$this->taskID = $taskID;
}

public function wait()
{
$this->client->waitForTask($this->indexName, $this->taskID);
}
}
14 changes: 14 additions & 0 deletions src/Responses/NullResponse.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace Algolia\SearchBundle\Responses;

/**
* @internal
*/
final class NullResponse
{
public function wait()
{
// no-op
}
}
Loading
Loading