Really rough fulltext driver implementation

This commit is contained in:
Toby Zerner 2015-06-04 11:11:56 +09:30
parent 42851f425b
commit aae7678cea
5 changed files with 43 additions and 7 deletions

View File

@ -2,6 +2,7 @@
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Migrations\Migration;
use DB;
class CreatePostsTable extends Migration class CreatePostsTable extends Migration
{ {
@ -14,7 +15,6 @@ class CreatePostsTable extends Migration
public function up() public function up()
{ {
Schema::create('posts', function (Blueprint $table) { Schema::create('posts', function (Blueprint $table) {
$table->increments('id'); $table->increments('id');
$table->integer('discussion_id')->unsigned(); $table->integer('discussion_id')->unsigned();
$table->integer('number')->unsigned()->nullable(); $table->integer('number')->unsigned()->nullable();
@ -29,10 +29,11 @@ class CreatePostsTable extends Migration
$table->integer('edit_user_id')->unsigned()->nullable(); $table->integer('edit_user_id')->unsigned()->nullable();
$table->dateTime('hide_time')->nullable(); $table->dateTime('hide_time')->nullable();
$table->integer('hide_user_id')->unsigned()->nullable(); $table->integer('hide_user_id')->unsigned()->nullable();
$table->unique(['discussion_id', 'number']);
}); });
// add fulltext index to content (and title?) DB::statement('ALTER TABLE posts ADD FULLTEXT content (content)');
// add unique index on [discussion_id, number] !!!
} }
/** /**

View File

@ -89,6 +89,11 @@ class CoreServiceProvider extends ServiceProvider
'Flarum\Core\Repositories\EloquentActivityRepository' 'Flarum\Core\Repositories\EloquentActivityRepository'
); );
$this->app->bind(
'Flarum\Core\Search\Discussions\Fulltext\DriverInterface',
'Flarum\Core\Search\Discussions\Fulltext\MySqlFulltextDriver'
);
$avatarFilesystem = function (Container $app) { $avatarFilesystem = function (Container $app) {
return $app->make('Illuminate\Contracts\Filesystem\Factory')->disk('flarum-avatars')->getDriver(); return $app->make('Illuminate\Contracts\Filesystem\Factory')->disk('flarum-avatars')->getDriver();
}; };

View File

@ -3,9 +3,17 @@
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
use Flarum\Core\Models\Post; use Flarum\Core\Models\Post;
use Flarum\Core\Models\User; use Flarum\Core\Models\User;
use Flarum\Core\Search\Discussions\Fulltext\DriverInterface;
class EloquentPostRepository implements PostRepositoryInterface class EloquentPostRepository implements PostRepositoryInterface
{ {
protected $fulltext;
public function __construct(DriverInterface $fulltext)
{
$this->fulltext = $fulltext;
}
/** /**
* Find a post by ID, optionally making sure it is visible to a certain * Find a post by ID, optionally making sure it is visible to a certain
* user, or throw an exception. * user, or throw an exception.
@ -72,10 +80,13 @@ class EloquentPostRepository implements PostRepositoryInterface
*/ */
public function findByContent($string, User $user = null) public function findByContent($string, User $user = null)
{ {
$query = Post::select('id', 'discussion_id') $ids = $this->fulltext->match($string);
->where('content', 'like', '%'.$string.'%');
// ->whereRaw('MATCH (`content`) AGAINST (? IN BOOLEAN MODE)', [$string]) $query = Post::select('id', 'discussion_id')->whereIn('id', $ids);
// ->orderByRaw('MATCH (`content`) AGAINST (?) DESC', [$string])
foreach ($ids as $id) {
$query->orderByRaw('id != ?', [$id]);
}
return $this->scopeVisibleForUser($query, $user)->get(); return $this->scopeVisibleForUser($query, $user)->get();
} }

View File

@ -0,0 +1,6 @@
<?php namespace Flarum\Core\Search\Discussions\Fulltext;
interface DriverInterface
{
public function match($string);
}

View File

@ -0,0 +1,13 @@
<?php namespace Flarum\Core\Search\Discussions\Fulltext;
use Flarum\Core\Models\Post;
class MySqlFulltextDriver implements DriverInterface
{
public function match($string)
{
return Post::whereRaw('MATCH (`content`) AGAINST (? IN BOOLEAN MODE)', [$string])
->orderByRaw('MATCH (`content`) AGAINST (?) DESC', [$string])
->lists('id');
}
}