Skip to content

Commit 939e698

Browse files
committed
searchableAs
1 parent c7b1ab7 commit 939e698

File tree

7 files changed

+174
-17
lines changed

7 files changed

+174
-17
lines changed

README.md

Lines changed: 79 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,18 +62,43 @@ return [
6262
];
6363
```
6464

65-
Migrate your database:
65+
## Creating the index
66+
67+
Models are indexed in a separate table. You can either create a single table
68+
and use it as a global index for all models, or create 1 index table per model
69+
(or a mix of both).
70+
71+
### Global index
72+
73+
The default name for the table is `searchindex`. If you want to use a different
74+
name, you can configure it in `config/scout.php`:
75+
76+
```php
77+
78+
return [
79+
// ...
80+
'sqlout' => [
81+
'table_name' => 'my_custom_index_name',
82+
// ...
83+
],
84+
// ...
85+
];
86+
87+
```
88+
89+
Then, migrate your database:
6690

6791
```bash
6892
php artisan sqlout:make-migration
6993
php artisan migrate
7094
```
7195

72-
This will create a `searchindex` table in your database (the table name can
73-
be customized in the config file).
96+
This will create the `searchindex` table (or whatever name you've configured).
97+
98+
### Different connections
7499

75100
If you want to index models that belong to different connections, you need
76-
a table for Sqlout on each connection. To create the table on a connection that
101+
an index table per connection. To create the table on a connection that
77102
is not the default connection, you can call the `sqlout:make-migration` command
78103
and pass the name of the connection:
79104

@@ -82,6 +107,48 @@ php artisan sqlout:make-migration my_other_connection
82107
php artisan migrate
83108
```
84109

110+
### Separate indexes
111+
112+
If you prefer to index each model in a different table, set the global
113+
index name to an empty string:
114+
115+
```php
116+
117+
return [
118+
// ...
119+
'sqlout' => [
120+
'table_name' => '',
121+
// ...
122+
],
123+
// ...
124+
];
125+
126+
```
127+
128+
Each model will be indexed in a table named like the model table
129+
followed by `_index`, eg. the `Post` model will be index in `posts_index`.
130+
131+
You can configure a different suffix, and also a prefix, in the config file:
132+
133+
```php
134+
135+
return [
136+
'prefix' => 'sqlout_',
137+
'suffix' => '',
138+
];
139+
140+
```
141+
142+
You can also customize the table name for each model with the `searchableAs` method
143+
(see [next section](#making-a-model-searchable)).
144+
145+
Once you're set up, create the index table for your models like this:
146+
147+
```bash
148+
php artisan sqlout:make-migration --model="\\App\\Models\\Post"
149+
php artisan migrate
150+
```
151+
85152
## Making a model searchable
86153

87154
```php
@@ -106,6 +173,14 @@ class Post extends Model
106173
'body' => $this->post_content,
107174
];
108175
}
176+
177+
// Optionally, you can customize the
178+
// name of the table that the model
179+
// will be indexed in:
180+
public function searchableAs(): string
181+
{
182+
return 'my_custom_index';
183+
}
109184
}
110185
```
111186

src/Engine.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ protected function newSearchQuery($model)
1616
$query = SearchIndex::query();
1717
$searchModel = $query->getModel()
1818
->setConnection($model->getConnectionName())
19-
->setTable(config('scout.sqlout.table_name'));
19+
->setTable($model->searchableAs());
2020
return $query->setModel($searchModel);
2121
}
2222

src/Migrations/MigrateMakeCommand.php

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,14 @@
66
use Illuminate\Database\Console\Migrations\MigrateMakeCommand as BaseCommand;
77
use Illuminate\Support\Composer;
88
use Illuminate\Support\Str;
9+
use InvalidArgumentException;
910

1011
class MigrateMakeCommand extends BaseCommand
1112
{
12-
protected $signature = 'sqlout:make-migration {connection? : Name of the connection}
13+
protected $signature = 'sqlout:make-migration
14+
{connection? : Name of the connection}
15+
{table? : Name of the table}
16+
{--model= : The model that the index is for}
1317
{--name= : The name of the migration.}
1418
{--path= : The location where the migration file should be created.}
1519
{--realpath : Indicate any provided migration file paths are pre-resolved absolute paths.}
@@ -23,23 +27,38 @@ public function __construct(MigrationCreator $creator, Composer $composer)
2327

2428
public function handle()
2529
{
26-
$connection = $this->input->getArgument('connection') ?? config('database.default');
30+
$name = $this->input->getOption('name');
31+
32+
if ($modelClass = $this->input->getOption('model')) {
33+
if (!class_exists($modelClass)) {
34+
throw new InvalidArgumentException("$modelClass class does not exist!");
35+
}
36+
if (!method_exists($modelClass, 'searchableAs')) {
37+
throw new InvalidArgumentException("$modelClass class is not searchable!");
38+
}
39+
$model = new $modelClass();
40+
$connection = $model->getConnectionName();
41+
$table = $model->searchableAs();
42+
$name = 'create sqlout index for ' . class_basename($modelClass);
43+
} else {
44+
$connection = $this->input->getArgument('connection') ?? config('database.default');
45+
$table = $this->input->getArgument('table') ?? config('scout.sqlout.table_name');
46+
$name = "create sqlout index $connection $table";
47+
}
2748

28-
$this->writeSqloutMigration($connection);
49+
$this->writeSqloutMigration($name, $connection, $table);
2950
$this->composer->dumpAutoloads();
3051

3152
if ($this->input->hasOption('migrate') && $this->option('migrate')) {
3253
$this->call('migrate');
3354
}
3455
}
3556

36-
protected function writeSqloutMigration($connection)
57+
protected function writeSqloutMigration($name, $connection, $tableName)
3758
{
3859
// Get the name for the migration file:
39-
$name = $this->input->getOption('name') ?: 'create_sqlout_index_for_' . $connection;
4060
$name = Str::snake(trim($name));
4161
$className = Str::studly($name);
42-
$tableName = config('scout.sqlout.table_name');
4362

4463
// Generate the content of the migration file:
4564
$contents = $this->getMigrationContents($className, $connection, $tableName);

src/Searchable.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,17 @@ public function getSearchWeight($field)
3535
{
3636
return $this->weights[$field] ?? 1;
3737
}
38+
39+
/**
40+
* Get the index name for the model when searching.
41+
*
42+
* @return string
43+
*/
44+
public function searchableAs()
45+
{
46+
return config(
47+
'scout.sqlout.table_name',
48+
config('scout.prefix').$this->getTable().config('scout.suffix', '_index')
49+
);
50+
}
3851
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
namespace Baril\Sqlout\Tests\Models;
4+
5+
class PostOtherSearchIndex extends Post
6+
{
7+
protected $table = 'posts';
8+
9+
public function searchableAs()
10+
{
11+
return 'other_searchindex';
12+
}
13+
}

tests/SearchTest.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,14 @@
66
use Baril\Sqlout\SearchIndex;
77
use Baril\Sqlout\Tests\Models\Comment;
88
use Baril\Sqlout\Tests\Models\Post;
9+
use Baril\Sqlout\Tests\Models\PostOtherSearchIndex;
910
use Illuminate\Contracts\Pagination\Paginator;
1011
use Illuminate\Database\Eloquent\Relations\Relation;
1112
use Illuminate\Support\Facades\DB as DB;
13+
use Illuminate\Support\Facades\File;
1214
use Illuminate\Support\LazyCollection;
1315
use Laravel\Scout\Builder as ScoutBuilder;
16+
use Orchestra\Testbench\Database\MigrateProcessor;
1417
use Wamania\Snowball\StemmerFactory;
1518

1619
class SearchTest extends TestCase
@@ -357,4 +360,41 @@ public function test_paginate()
357360
array_map(function ($item) { return $item->id; }, $paginator->items())
358361
);
359362
}
363+
364+
public function test_other_index()
365+
{
366+
$path = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'migrations';
367+
File::deleteDirectory($path);
368+
File::makeDirectory($path);
369+
370+
$this->artisan('sqlout:make-migration', [
371+
'--model' => PostOtherSearchIndex::class,
372+
'--path' => $path,
373+
'--realpath' => true,
374+
]);
375+
376+
$this->assertCount(1, File::allFiles($path));
377+
378+
$migrator = new MigrateProcessor($this, [
379+
'--path' => $path,
380+
'--realpath' => true,
381+
]);
382+
$migrator->up();
383+
384+
$this->assertTrue(DB::getSchemaBuilder()->hasTable('other_searchindex'));
385+
386+
PostOtherSearchIndex::unguard();
387+
PostOtherSearchIndex::create([
388+
'title' => 'kiki',
389+
'body' => 'kuku',
390+
]);
391+
392+
$this->assertNotEmpty(DB::table('other_searchindex')->get());
393+
394+
$search = PostOtherSearchIndex::search('kiki');
395+
$this->assertEquals(1, $search->count());
396+
397+
// Cleaning stuff:
398+
File::deleteDirectory($path);
399+
}
360400
}

tests/TestCase.php

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Baril\Sqlout\SqloutServiceProvider;
66
use Dotenv\Dotenv;
7+
use Illuminate\Support\Facades\DB;
78
use Laravel\Scout\ScoutServiceProvider;
89
use Orchestra\Testbench\TestCase as OrchestraTestCase;
910

@@ -96,12 +97,8 @@ protected function getPackageProviders($app)
9697
protected function setUp(): void
9798
{
9899
parent::setUp();
100+
DB::getSchemaBuilder()->dropAllTables();
99101
$this->loadMigrationsFrom(__DIR__ . '/database/migrations');
100-
\DB::enableQueryLog();
101-
}
102-
103-
protected function dumpQueryLog()
104-
{
105-
dump(\DB::getQueryLog());
102+
DB::enableQueryLog();
106103
}
107104
}

0 commit comments

Comments
 (0)