Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support search indexes in mappings and SchemaManager #2630

Merged
merged 15 commits into from
May 22, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Support search indexes in CLI commands
Adds default implementations for "process" methods in AbstractCommand, which throw BadMethodCallException.

Renames internal methods in ShardCommand to no longer override "index" base methods, since sharding methods in SchemaManager do much more than process indexes.
  • Loading branch information
jmikola committed May 13, 2024
commit 2cb83acf4b375c110c1acab95e81ece59b82eafa
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Doctrine\ODM\MongoDB\Tools\Console\Command\Schema;

use BadMethodCallException;
use Doctrine\ODM\MongoDB\DocumentManager;
use Doctrine\ODM\MongoDB\Mapping\ClassMetadataFactoryInterface;
use Doctrine\ODM\MongoDB\SchemaManager;
Expand All @@ -18,9 +19,10 @@

abstract class AbstractCommand extends Command
{
public const DB = 'db';
public const COLLECTION = 'collection';
public const INDEX = 'index';
public const DB = 'db';
public const COLLECTION = 'collection';
public const INDEX = 'index';
public const SEARCH_INDEX = 'search-index';

/** @return void */
protected function configure()
Expand All @@ -34,23 +36,81 @@ protected function configure()
->addOption('journal', null, InputOption::VALUE_REQUIRED, 'An optional journal option for the write concern that will be used for all schema operations. Using this option without a w option will cause an exception to be thrown.');
}

/** @return void */
abstract protected function processDocumentCollection(SchemaManager $sm, string $document, ?int $maxTimeMs, ?WriteConcern $writeConcern);
/**
* @return void
*
* @throws BadMethodCallException
*/
protected function processDocumentCollection(SchemaManager $sm, string $document, ?int $maxTimeMs, ?WriteConcern $writeConcern)
{
throw new BadMethodCallException('This command does not support collections');
}

/** @return void */
abstract protected function processCollection(SchemaManager $sm, ?int $maxTimeMs, ?WriteConcern $writeConcern);
/**
* @return void
*
* @throws BadMethodCallException
*/
protected function processCollection(SchemaManager $sm, ?int $maxTimeMs, ?WriteConcern $writeConcern)
{
throw new BadMethodCallException('This command does not support collections');
}

/** @return void */
abstract protected function processDocumentDb(SchemaManager $sm, string $document, ?int $maxTimeMs, ?WriteConcern $writeConcern);
/**
* @return void
*
* @throws BadMethodCallException
*/
protected function processDocumentDb(SchemaManager $sm, string $document, ?int $maxTimeMs, ?WriteConcern $writeConcern)
{
throw new BadMethodCallException('This command does not support databases');
}

/** @return void */
abstract protected function processDb(SchemaManager $sm, ?int $maxTimeMs, ?WriteConcern $writeConcern);
/**
* @return void
*
* @throws BadMethodCallException
*/
protected function processDb(SchemaManager $sm, ?int $maxTimeMs, ?WriteConcern $writeConcern)
{
throw new BadMethodCallException('This command does not support databases');
}

/** @return void */
abstract protected function processDocumentIndex(SchemaManager $sm, string $document, ?int $maxTimeMs, ?WriteConcern $writeConcern);
/**
* @return void
*
* @throws BadMethodCallException
*/
protected function processDocumentIndex(SchemaManager $sm, string $document, ?int $maxTimeMs, ?WriteConcern $writeConcern)
{
throw new BadMethodCallException('This command does not support indexes');
}

/** @return void */
abstract protected function processIndex(SchemaManager $sm, ?int $maxTimeMs, ?WriteConcern $writeConcern);
/**
* @return void
*
* @throws BadMethodCallException
*/
protected function processIndex(SchemaManager $sm, ?int $maxTimeMs, ?WriteConcern $writeConcern)
{
throw new BadMethodCallException('This command does not support indexes');
}

/** @throws BadMethodCallException */
protected function processSearchIndex(SchemaManager $sm): void
{
throw new BadMethodCallException('This command does not support search indexes');
}

/**
* @psalm-param class-string $document
*
* @throws BadMethodCallException
*/
protected function processDocumentSearchIndex(SchemaManager $sm, string $document): void
{
throw new BadMethodCallException('This command does not support search indexes');
}

/** @return SchemaManager */
protected function getSchemaManager()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

namespace Doctrine\ODM\MongoDB\Tools\Console\Command\Schema;

use BadMethodCallException;
use Doctrine\ODM\MongoDB\SchemaManager;
use Doctrine\ODM\MongoDB\Tools\Console\Command\CommandCompatibility;
use MongoDB\Driver\WriteConcern;
Expand All @@ -16,14 +15,20 @@
use function array_filter;
use function is_string;
use function sprintf;
use function ucfirst;

class CreateCommand extends AbstractCommand
{
use CommandCompatibility;

/** @var string[] */
private array $createOrder = [self::COLLECTION, self::INDEX];
private array $createOrder = [self::COLLECTION, self::INDEX, self::SEARCH_INDEX];

/* @var array<string, list<string>> */
private const INFLECTIONS = [
self::COLLECTION => ['collection', 'collections'],
self::INDEX => ['index(es)', 'indexes'],
self::SEARCH_INDEX => ['search index(es)', 'search indexes'],
];

/** @return void */
protected function configure()
Expand All @@ -35,6 +40,7 @@ protected function configure()
->addOption('class', 'c', InputOption::VALUE_REQUIRED, 'Document class to process (default: all classes)')
->addOption(self::COLLECTION, null, InputOption::VALUE_NONE, 'Create collections')
->addOption(self::INDEX, null, InputOption::VALUE_NONE, 'Create indexes')
->addOption(self::SEARCH_INDEX, null, InputOption::VALUE_NONE, 'Create search indexes')
->addOption('background', null, InputOption::VALUE_NONE, sprintf('Create indexes in background (requires "%s" option)', self::INDEX))
->setDescription('Create databases, collections and indexes for your documents');
}
Expand All @@ -53,17 +59,22 @@ private function doExecute(InputInterface $input, OutputInterface $output): int
$isErrored = false;

foreach ($create as $option) {
$method = match ($option) {
self::COLLECTION => 'Collection',
self::INDEX => 'Index',
self::SEARCH_INDEX => 'SearchIndex',
};

try {
if (isset($class)) {
$this->{'processDocument' . ucfirst($option)}($sm, $class, $this->getMaxTimeMsFromInput($input), $this->getWriteConcernFromInput($input), $background);
$this->{'processDocument' . $method}($sm, $class, $this->getMaxTimeMsFromInput($input), $this->getWriteConcernFromInput($input), $background);
} else {
$this->{'process' . ucfirst($option)}($sm, $this->getMaxTimeMsFromInput($input), $this->getWriteConcernFromInput($input), $background);
$this->{'process' . $method}($sm, $this->getMaxTimeMsFromInput($input), $this->getWriteConcernFromInput($input), $background);
}

$output->writeln(sprintf(
'Created <comment>%s%s</comment> for <info>%s</info>',
$option,
is_string($class) ? ($option === self::INDEX ? '(es)' : '') : ($option === self::INDEX ? 'es' : 's'),
'Created <comment>%s</comment> for <info>%s</info>',
self::INFLECTIONS[$option][isset($class) ? 0 : 1],
is_string($class) ? $class : 'all classes'
));
} catch (Throwable $e) {
Expand All @@ -85,24 +96,24 @@ protected function processCollection(SchemaManager $sm, ?int $maxTimeMs, ?WriteC
$sm->createCollections($maxTimeMs, $writeConcern);
}

protected function processDocumentDb(SchemaManager $sm, string $document, ?int $maxTimeMs, ?WriteConcern $writeConcern)
protected function processDocumentIndex(SchemaManager $sm, string $document, ?int $maxTimeMs, ?WriteConcern $writeConcern, bool $background = false)
{
throw new BadMethodCallException('A database is created automatically by MongoDB (>= 3.0).');
$sm->ensureDocumentIndexes($document, $maxTimeMs, $writeConcern, $background);
}

protected function processDb(SchemaManager $sm, ?int $maxTimeMs, ?WriteConcern $writeConcern)
protected function processIndex(SchemaManager $sm, ?int $maxTimeMs, ?WriteConcern $writeConcern, bool $background = false)
{
throw new BadMethodCallException('A database is created automatically by MongoDB (>= 3.0).');
$sm->ensureIndexes($maxTimeMs, $writeConcern, $background);
}

protected function processDocumentIndex(SchemaManager $sm, string $document, ?int $maxTimeMs, ?WriteConcern $writeConcern, bool $background = false)
protected function processDocumentSearchIndex(SchemaManager $sm, string $document): void
{
$sm->ensureDocumentIndexes($document, $maxTimeMs, $writeConcern, $background);
$sm->createDocumentSearchIndexes($document);
}

protected function processIndex(SchemaManager $sm, ?int $maxTimeMs, ?WriteConcern $writeConcern, bool $background = false)
protected function processSearchIndex(SchemaManager $sm): void
{
$sm->ensureIndexes($maxTimeMs, $writeConcern, $background);
$sm->createSearchIndexes();
}

/** @return void */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,21 @@
use function array_filter;
use function is_string;
use function sprintf;
use function ucfirst;

class DropCommand extends AbstractCommand
{
use CommandCompatibility;

/** @var string[] */
private array $dropOrder = [self::INDEX, self::COLLECTION, self::DB];
private array $dropOrder = [self::SEARCH_INDEX, self::INDEX, self::COLLECTION, self::DB];

/* @var array<string, list<string>> */
private const INFLECTIONS = [
self::DB => ['database', 'databases'],
self::COLLECTION => ['collection', 'collections'],
self::INDEX => ['index(es)', 'indexes'],
self::SEARCH_INDEX => ['search index(es)', 'search indexes'],
];

/** @return void */
protected function configure()
Expand All @@ -35,6 +42,7 @@ protected function configure()
->addOption(self::DB, null, InputOption::VALUE_NONE, 'Drop databases')
->addOption(self::COLLECTION, null, InputOption::VALUE_NONE, 'Drop collections')
->addOption(self::INDEX, null, InputOption::VALUE_NONE, 'Drop indexes')
->addOption(self::SEARCH_INDEX, null, InputOption::VALUE_NONE, 'Drop search indexes')
->setDescription('Drop databases, collections and indexes for your documents');
}

Expand All @@ -50,17 +58,23 @@ private function doExecute(InputInterface $input, OutputInterface $output): int
$isErrored = false;

foreach ($drop as $option) {
$method = match ($option) {
self::DB => 'Db',
self::COLLECTION => 'Collection',
self::INDEX => 'Index',
self::SEARCH_INDEX => 'SearchIndex',
};

try {
if (is_string($class)) {
$this->{'processDocument' . ucfirst($option)}($sm, $class, $this->getMaxTimeMsFromInput($input), $this->getWriteConcernFromInput($input));
$this->{'processDocument' . $method}($sm, $class, $this->getMaxTimeMsFromInput($input), $this->getWriteConcernFromInput($input));
} else {
$this->{'process' . ucfirst($option)}($sm, $this->getMaxTimeMsFromInput($input), $this->getWriteConcernFromInput($input));
$this->{'process' . $method}($sm, $this->getMaxTimeMsFromInput($input), $this->getWriteConcernFromInput($input));
}

$output->writeln(sprintf(
'Dropped <comment>%s%s</comment> for <info>%s</info>',
$option,
is_string($class) ? ($option === self::INDEX ? '(es)' : '') : ($option === self::INDEX ? 'es' : 's'),
'Dropped <comment>%s</comment> for <info>%s</info>',
self::INFLECTIONS[$option][isset($class) ? 0 : 1],
is_string($class) ? $class : 'all classes'
));
} catch (Throwable $e) {
Expand Down Expand Up @@ -101,4 +115,14 @@ protected function processIndex(SchemaManager $sm, ?int $maxTimeMs, ?WriteConcer
{
$sm->deleteIndexes($maxTimeMs, $writeConcern);
}

protected function processDocumentSearchIndex(SchemaManager $sm, string $document): void
{
$sm->deleteDocumentSearchIndexes($document);
}

protected function processSearchIndex(SchemaManager $sm): void
{
$sm->deleteSearchIndexes();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

namespace Doctrine\ODM\MongoDB\Tools\Console\Command\Schema;

use BadMethodCallException;
use Doctrine\ODM\MongoDB\SchemaManager;
use Doctrine\ODM\MongoDB\Tools\Console\Command\CommandCompatibility;
use MongoDB\Driver\WriteConcern;
Expand Down Expand Up @@ -40,10 +39,10 @@ private function doExecute(InputInterface $input, OutputInterface $output): int

try {
if (is_string($class)) {
$this->processDocumentIndex($sm, $class, null, $this->getWriteConcernFromInput($input));
$this->processDocumentSharding($sm, $class, $this->getWriteConcernFromInput($input));
$output->writeln(sprintf('Enabled sharding for <info>%s</info>', $class));
} else {
$this->processIndex($sm, null, $this->getWriteConcernFromInput($input));
$this->processSharding($sm, $this->getWriteConcernFromInput($input));
$output->writeln('Enabled sharding for <info>all classes</info>');
}
} catch (Throwable $e) {
Expand All @@ -54,37 +53,14 @@ private function doExecute(InputInterface $input, OutputInterface $output): int
return $isErrored ? 255 : 0;
}

protected function processDocumentIndex(SchemaManager $sm, string $document, ?int $maxTimeMs = null, ?WriteConcern $writeConcern = null)
/** @psalm-param class-string $document */
private function processDocumentSharding(SchemaManager $sm, string $document, ?WriteConcern $writeConcern = null): void
{
$sm->ensureDocumentSharding($document, $writeConcern);
}

protected function processIndex(SchemaManager $sm, ?int $maxTimeMs = null, ?WriteConcern $writeConcern = null)
private function processSharding(SchemaManager $sm, ?WriteConcern $writeConcern = null): void
{
$sm->ensureSharding($writeConcern);
}

/** @throws BadMethodCallException */
protected function processDocumentCollection(SchemaManager $sm, string $document, ?int $maxTimeMs, ?WriteConcern $writeConcern)
{
throw new BadMethodCallException('Cannot update a document collection');
}

/** @throws BadMethodCallException */
protected function processCollection(SchemaManager $sm, ?int $maxTimeMs, ?WriteConcern $writeConcern)
{
throw new BadMethodCallException('Cannot update a collection');
}

/** @throws BadMethodCallException */
protected function processDocumentDb(SchemaManager $sm, string $document, ?int $maxTimeMs, ?WriteConcern $writeConcern)
{
throw new BadMethodCallException('Cannot update a document database');
}

/** @throws BadMethodCallException */
protected function processDb(SchemaManager $sm, ?int $maxTimeMs, ?WriteConcern $writeConcern)
{
throw new BadMethodCallException('Cannot update a database');
}
}
Loading