Skip to content

Commit f7b6dbe

Browse files
committed
Add command to create indexes without importing documents
1 parent 682a272 commit f7b6dbe

File tree

2 files changed

+129
-0
lines changed

2 files changed

+129
-0
lines changed
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace MeiliSearch\Bundle\Command;
6+
7+
use MeiliSearch\Bundle\Exception\InvalidSettingName;
8+
use MeiliSearch\Bundle\Exception\UpdateException;
9+
use MeiliSearch\Bundle\Model\Aggregator;
10+
use MeiliSearch\Bundle\SearchService;
11+
use MeiliSearch\Client;
12+
use Symfony\Component\Console\Input\InputInterface;
13+
use Symfony\Component\Console\Input\InputOption;
14+
use Symfony\Component\Console\Output\OutputInterface;
15+
16+
final class MeiliSearchCreateCommand extends IndexCommand
17+
{
18+
protected static $defaultName = 'meili:create';
19+
20+
private Client $searchClient;
21+
22+
public function __construct(SearchService $searchService, Client $searchClient)
23+
{
24+
parent::__construct($searchService);
25+
26+
$this->searchClient = $searchClient;
27+
}
28+
29+
protected function configure(): void
30+
{
31+
$this
32+
->setDescription('Create indexes')
33+
->addOption('indices', 'i', InputOption::VALUE_OPTIONAL, 'Comma-separated list of index names');
34+
}
35+
36+
protected function execute(InputInterface $input, OutputInterface $output): int
37+
{
38+
$indexes = $this->getEntitiesFromArgs($input, $output);
39+
40+
foreach ($indexes as $key => $index) {
41+
$entityClassName = $index['class'];
42+
if (is_subclass_of($entityClassName, Aggregator::class)) {
43+
$indexes->forget($key);
44+
45+
$indexes = collect(array_merge(
46+
$indexes->toArray(),
47+
array_map(
48+
static fn ($entity) => ['name' => $index['name'], 'class' => $entity],
49+
$entityClassName::getEntities()
50+
)
51+
));
52+
}
53+
}
54+
55+
$entitiesToIndex = array_unique($indexes->toArray(), SORT_REGULAR);
56+
57+
/** @var array $index */
58+
foreach ($entitiesToIndex as $index) {
59+
$entityClassName = $index['class'];
60+
61+
if (!$this->searchService->isSearchable($entityClassName)) {
62+
continue;
63+
}
64+
65+
$output->writeln('<info>Creating index '.$index['name'].' for '.$entityClassName.'</info>');
66+
67+
$indexInstance = $this->searchClient->getOrCreateIndex($index['name']);
68+
69+
if (isset($index['settings']) && is_array($index['settings'])) {
70+
foreach ($index['settings'] as $variable => $value) {
71+
$method = sprintf('update%s', ucfirst($variable));
72+
73+
if (false === method_exists($indexInstance, $method)) {
74+
throw new InvalidSettingName(sprintf('Invalid setting name: "%s"', $variable));
75+
}
76+
77+
$update = $indexInstance->{$method}($value);
78+
79+
$indexInstance->waitForPendingUpdate($update['updateId']);
80+
$updateStatus = $indexInstance->getUpdateStatus($update['updateId']);
81+
82+
if ('failed' === $updateStatus['status']) {
83+
throw new UpdateException($updateStatus['error']);
84+
}
85+
}
86+
}
87+
}
88+
89+
$output->writeln('<info>Done!</info>');
90+
91+
return 0;
92+
}
93+
}

tests/Integration/CommandsTest.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,4 +213,40 @@ public function testImportingIndexNameWithAndWithoutPrefix(): void
213213
$this->assertStringContainsString('Done!', $output);
214214
$this->assertSame(0, $return);
215215
}
216+
217+
public function testSearchCreateWithoutIndices(): void
218+
{
219+
$createCommand = $this->application->find('meili:create');
220+
$createCommandTester = new CommandTester($createCommand);
221+
$createCommandTester->execute([]);
222+
223+
$createOutput = $createCommandTester->getDisplay();
224+
225+
$this->assertSame(<<<'EOD'
226+
Creating index for MeiliSearch\Bundle\Test\Entity\Post
227+
Creating index index for MeiliSearch\Bundle\Test\Entity\Comment
228+
Creating index index for MeiliSearch\Bundle\Test\Entity\Tag
229+
Creating index index for MeiliSearch\Bundle\Test\Entity\Link
230+
Creating index index for MeiliSearch\Bundle\Test\Entity\Page
231+
Done!
232+
233+
EOD, $createOutput);
234+
}
235+
236+
public function testSearchCreateWithIndices(): void
237+
{
238+
$createCommand = $this->application->find('meili:create');
239+
$createCommandTester = new CommandTester($createCommand);
240+
$createCommandTester->execute([
241+
'--indices' => 'posts',
242+
]);
243+
244+
$createOutput = $createCommandTester->getDisplay();
245+
246+
$this->assertSame(<<<'EOD'
247+
Creating index for MeiliSearch\Bundle\Test\Entity\Post
248+
Done!
249+
250+
EOD, $createOutput);
251+
}
216252
}

0 commit comments

Comments
 (0)