<?php
declare(strict_types=1);
namespace Pimcore\Bundle\GenericDataIndexBundle\SearchIndexAdapter\DefaultSearch\DataObject;
use Pimcore\Bundle\GenericDataIndexBundle\Enum\SearchIndex\FieldCategory\SystemField;
use Pimcore\Bundle\GenericDataIndexBundle\SearchIndexAdapter\DataObject\IndexIconUpdateServiceInterface;
use Pimcore\SearchClient\SearchClientInterface;
final readonly class IndexIconUpdateServiceNoupdateByQuery implements IndexIconUpdateServiceInterface
{
public function __construct(private SearchClientInterface $client)
{
}
public function updateIcon(string $indexName, ?string $icon): void
{
$query = $icon === null ? $this->getQueryForNullIcon() : $this->getQueryForIconString($icon);
// 1) start scroll
$response = $this->client->search([
'index' => $indexName,
'scroll' => '1m',
'_source' => false,
'body' => [
'query' => $query,
'size' => 1000,
],
]);
$scrollId = $response['_scroll_id'] ?? null;
$hits = $response['hits']['hits'] ?? [];
while ($scrollId && !empty($hits)) {
// 2) build bulk updates
$bulk = ['body' => []];
foreach ($hits as $hit) {
$id = $hit['_id'];
$bulk['body'][] = [
'update' => [
'_index' => $indexName,
'_id' => $id,
],
];
$bulk['body'][] = [
'doc' => [
'system_fields' => [
'classDefinitionIcon' => $icon,
],
],
];
}
if (!empty($bulk['body'])) {
$this->client->bulk($bulk);
}
// 3) next page
$response = $this->client->scroll([
'scroll_id' => $scrollId,
'scroll' => '1m',
]);
$scrollId = $response['_scroll_id'] ?? null;
$hits = $response['hits']['hits'] ?? [];
}
if ($scrollId) {
$this->client->clearScroll(['scroll_id' => $scrollId]);
}
// Optional: refresh index if you need immediate visibility
// $this->client->refreshIndex(['index' => $indexName]);
}
// this code can be shared with IndexIconUpdateService
private function getQueryForNullIcon(): array
{
return [
'bool' => [
'filter' => [
'exists' => ['field' => SystemField::CLASS_DEFINITION_ICON->getPath()],
],
],
];
}
// this code can be shared with IndexIconUpdateService
private function getQueryForIconString(string $icon): array
{
return [
'bool' => [
'should' => [
[
'bool' => [
'must_not' => [
'exists' => ['field' => SystemField::CLASS_DEFINITION_ICON->getPath()],
],
],
],
[
'bool' => [
'must_not' => [
'term' => [SystemField::CLASS_DEFINITION_ICON->getPath() => $icon],
],
],
],
],
'minimum_should_match' => 1,
],
];
}
}
Some OpenSearch servers may not support
updateByQuery. The only place that looks to callupdateByQueryisupdateIcon.An alternative implementation of
IndexIconUpdateServiceInterfacethat works around it looks roughly like: