[performance] Optimize hyperf/scout, add --chunk and --column|c options to the scout:import command (#2883)

* perf: Optimize scout, use chunkById() instead of chunk()

* feat: Add `--chunk` and `--column|c` options to the scout:import command

* Update phpunit.xml

* Update CHANGELOG-2.0.md

Co-authored-by: 李铭昕 <715557344@qq.com>
This commit is contained in:
Fangx 2020-11-30 10:25:08 +08:00 committed by GitHub
parent 17d8a40834
commit c9ff54bbb4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 28 additions and 9 deletions

View File

@ -5,6 +5,7 @@
- [#2857](https://github.com/hyperf/hyperf/pull/2857) Support Consul ACL Token for Service Governance.
- [#2870](https://github.com/hyperf/hyperf/pull/2870) The publish option of `ConfigProvider` allows publish directory.
- [#2875](https://github.com/hyperf/hyperf/pull/2875) Added option `no-restart` for watcher.
- [#2883](https://github.com/hyperf/hyperf/pull/2883) Added options `--chunk` and `--column|c` into command `scout:import`.
- [#2891](https://github.com/hyperf/hyperf/pull/2891) Added config file for crontab.
## Fixed

View File

@ -48,6 +48,7 @@
<directory suffix="Test.php">./src/retry/tests</directory>
<directory suffix="Test.php">./src/rpc/tests</directory>
<directory suffix="Test.php">./src/rpc-server/tests</directory>
<directory suffix="Test.php">./src/scout/tests</directory>
<directory suffix="Test.php">./src/server/tests</directory>
<directory suffix="Test.php">./src/service-governance/tests</directory>
<directory suffix="Test.php">./src/session/tests</directory>
@ -93,6 +94,7 @@
<directory suffix=".php">./src/paginator/src</directory>
<directory suffix=".php">./src/redis/src</directory>
<directory suffix=".php">./src/rpc/src</directory>
<directory suffix=".php">./src/scout/src</directory>
<directory suffix=".php">./src/server/src</directory>
<directory suffix=".php">./src/service-governance/src</directory>
<directory suffix=".php">./src/session/src</directory>

View File

@ -664,9 +664,9 @@ class Builder
*/
public function chunkById($count, callable $callback, $column = null, $alias = null)
{
$column = is_null($column) ? $this->getModel()->getKeyName() : $column;
$column = $column ?? $this->getModel()->getKeyName();
$alias = is_null($alias) ? $column : $alias;
$alias = $alias ?? $column;
$lastId = null;

View File

@ -16,6 +16,7 @@ use Hyperf\Scout\Event\ModelsImported;
use Hyperf\Utils\ApplicationContext;
use Psr\EventDispatcher\ListenerProviderInterface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
class ImportCommand extends Command
{
@ -40,16 +41,27 @@ class ImportCommand extends Command
{
define('SCOUT_COMMAND', true);
$class = $this->input->getArgument('model');
$chunk = (int) $this->input->getOption('chunk');
$column = (string) $this->input->getOption('column');
$model = new $class();
$provider = ApplicationContext::getContainer()->get(ListenerProviderInterface::class);
$provider->on(ModelsImported::class, function ($event) use ($class) {
/** @var ModelsImported $event */
$key = $event->models->last()->getScoutKey();
$this->line('<comment>Imported [' . $class . '] models up to ID:</comment> ' . $key);
});
$model::makeAllSearchable();
$model::makeAllSearchable($chunk ?: null, $column ?: null);
$this->info('All [' . $class . '] records have been imported.');
}
protected function getOptions()
{
return [
['column', 'c', InputOption::VALUE_OPTIONAL, 'Column used in chunking. (Default use primary key)'],
['chunk', '', InputOption::VALUE_OPTIONAL, 'The number of records to import at a time (Defaults to configuration value: `scout.chunk.searchable`)'],
];
}
protected function getArguments()
{
return [

View File

@ -111,7 +111,7 @@ trait Searchable
/**
* Make all instances of the model searchable.
*/
public static function makeAllSearchable()
public static function makeAllSearchable(?int $chunk = null, ?string $column = null)
{
$self = new static();
$softDelete = static::usesSoftDelete() && config('scout.soft_delete', false);
@ -119,8 +119,8 @@ trait Searchable
->when($softDelete, function ($query) {
$query->withTrashed();
})
->orderBy($self->getKeyName())
->searchable();
->orderBy($column ?: $self->getKeyName())
->searchable($chunk, $column);
}
/**

View File

@ -33,12 +33,16 @@ class SearchableScope implements Scope
*/
public function extend(EloquentBuilder $builder)
{
$builder->macro('searchable', function (EloquentBuilder $builder, $chunk = null) {
$builder->chunk($chunk ?: config('scout.chunk.searchable', 500), function ($models) {
$builder->macro('searchable', function (EloquentBuilder $builder, $chunk = null, $column = null) {
$callback = function ($models) {
$models->filter->shouldBeSearchable()->searchable();
$dispatcher = ApplicationContext::getContainer()->get(EventDispatcherInterface::class);
$dispatcher->dispatch(new ModelsImported($models));
});
};
$chunk = $chunk ?: config('scout.chunk.searchable', 500);
$column ? $builder->chunkById($chunk, $callback, $column) : $builder->chunk($chunk, $callback);
});
$builder->macro('unsearchable', function (EloquentBuilder $builder, $chunk = null) {
$builder->chunk($chunk ?: config('scout.chunk.unsearchable', 500), function ($models) {