やること
全文検索機能を実装してみる環境
Laravel 5.8目次
1.Algoliaってなんぞやという話 2.LaravelでAlgoliaを使う準備 3.検索テストするためのダミーデータ作成+Algoliaにデータ追加 4.実際に検索する!Algoliaってなんぞやという話
Algoriaは全文検索エンジンのサービスで、人気が高まってる。 ホームページ→ https://www.algolia.com/ 緯度経度データ登録すれば位置情報検索も簡単に実装できるみたいです。また今回はLaravelで実装しますが他の言語・フレームワークでも自由に使えるっぽい。サイト内のどこに何があるかわかりにくいですがそこがわかれば各々の説明はとても親切だと思います。
LaravelでAlgoliaを使う準備
まず以下のコマンドでScoutをインストールします。composer require laravel/scout
これでScoutが使えるようになります。ScoutについてはLaravel公式ドキュメントに詳しく書いてあります。
次に以下のコマンドでconfigディレクトリ内にscout.php
を作ります。
php artisan vendor:publish --provider="Laravel\Scout\ScoutServiceProvider"
次にscout.php
に
'queue' => true,
を追加してキューの設定を行います。
次に、Algoliaのアカウントを作成し、APIキーとシークレットキーを得ます。
ちなみに初回トライアル無料期間は14日間で、その後は毎月お金がかかってしまいます。。。また、無料期間はレコード数の最大数も少なくなっています。(フリーだと1万件、月額だとプランによって変わってきます。詳しくは公式サイトで)
筆者は会社の隣の席の人にキーを借りているので作成方法とかはわからないですごめんなさい()
そしてキーを生成したら.env
ファイルに以下を追加してください。
ALGOLIA_APP_ID=生成したAPIキー
ALGOLIA_SECRET=生成したシークレットキー
最後にAlgolia PHP SDKを以下のコマンドでインストールして準備完了。
composer require algolia/algoliasearch-client-php:^2.2
検索テストするためのダミーデータ作成+Algoliaにデータ追加
まず、検索がちゃんと動くかの確認のためにダミーデータをFakerを使って作ります。 まずターミナルから以下のコマンドでFakerを使えるようにしておきます。composer require fzaninotto/faker
今回はpeopleテーブルを作成することにします。ということで、ターミナルで
php artisan make:migration create_people_table
php artisan make:seed PeopleTableSeeder
php artisan make:factory PersonFactory
database/factories以下にPersonFactory.php
ができているので以下のように変更します。
<?php
/* @var $factory \Illuminate\Database\Eloquent\Factory */
use App\Model;
use Faker\Generator as Faker;
$factory->define(App\Person::class, function (Faker $faker) {
return [
'last_name' => $faker->lastName,
'first_name' => $faker->firstName,
'company' => $faker->company,
'location' => $faker->city,
'birth_year' => $faker->year,
'birth_month' => $faker->month,
];
});
次にシーダーファイルを以下のように変更
<?php
use Illuminate\Database\Seeder;
class PeopleTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
factory(App\Person::class, 1000)->create();
}
}
1000のところは作成するダミーデータの数なのでお好みで〜
最後にDatabaseSeeder.php
を以下のようにして、
<?php
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*
* @return void
*/
public function run()
{
$this->call(PeopleTableSeeder::class);
}
}
シーディングじゃ!
php artisan db:seed
ここまでやるとデータベースのpeopleテーブルに1000件ダミーデータが入ってると思います。
次にこのデータをAlgoriaの方に渡して全文検索ができるようにします。
まずPersonモデルを作っておきます。
php artisan make:model PersonModel
そしてモデルを以下のように変更します。
<?php
namespace App;
use Laravel\Scout\Searchable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\Model;
class Person extends Model
{
use Searchable;
use Notifiable;
public function searchableAs()
{
return 'people_index';
}
public function toSearchableArray()
{
$array = $this->toArray();
$array = $this->transform($array);
return $array;
}
}
searchableAsメソッドに追加した'people_index'
によってAlgolia側にpeopleというテーブル(?)が作成されます。
public function searchableAs()
{
return 'people_index';
}
toSearchableArrayメソッドにはどのようなデータを追加するのかが記述されています。
Laravelの公式ドキュメントには記述がなかったのですが、toSearchableArrayにはwhereやwhereBetweenで必要なnumeric valueが定義されてないので、このような処理を行いたい場合には$array = $this->transform($array);
を追加してデータの型の変換を行うとできるようになるそうです。
次に検索ドライバにデータを追加します。以下のコマンドで完了。
php artisan scout:import 'App\Person'
実際に検索する!
検索結果を得るためのControllerを作成します。php artisan make:controller PersonController
としたのち、コントローラーを以下の用に編集します。
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Name;
use App\Person;
class PersonController extends Controller
{
public function index(Request $request){
$results = Person::search($request->str_1)->get();
return view('top.index')->with('results',$results);
}
}
(全文検索フォームのinputのnameをstr_1としています)
(ルーティングとviewの書き方は省略します)
ここまでできれば、検索フォームで好きな文字列を入力して検索ができます。ちなみに$results
をそのままviewで表示させるとjson型で返ってきていることが確認できます!
最後に
とにかく実装が楽でした。 他にも色々カスタマイズできるみたいです。実装していく中で気がついた点をまた投稿できたらなと。 今回参考文献はLaravel公式ドキュメントしかないです。stackshareで調べてみるとAmazon elasticsearch serviceから乗り換えている人も結構いるみたいでAlgoliaの方が高く評価されていた!(と思う)
お金はかかるけどやっぱり有料コンテンツって最高なんやな〜
追記
Fakerはデフォルトだと英語で入ってしまうので、日本語のデータが欲しい場合は`config/app.php`に'faker_locale'=>'ja_JP'
を追記してください!
多分キャッシュが残っているのでターミナルで
php artisan config:cache
を忘れずに。