5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Lalavel ScoutでAlgoliaを使って全文検索を実装してみた!

Last updated at Posted at 2019-07-18

やること

全文検索機能を実装してみる

環境

Laravel 5.8

目次

1.Algoliaってなんぞやという話 2.LaravelでAlgoliaを使う準備 3.検索テストするためのダミーデータ作成+Algoliaにデータ追加 4.実際に検索する!

Algoliaってなんぞやという話

Algoriaは全文検索エンジンのサービスで、人気が高まってる。 ホームページ→ https://www.algolia.com/ 緯度経度データ登録すれば位置情報検索も簡単に実装できるみたいです。また今回はLaravelで実装しますが他の言語・フレームワークでも自由に使えるっぽい。

ここのDocumentationから
image.png

API REFERENCEで選択できますよ!
image.png

サイト内のどこに何があるかわかりにくいですがそこがわかれば各々の説明はとても親切だと思います。

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ができているので以下のように変更します。

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,
    ];
});

次にシーダーファイルを以下のように変更

PeopleTableSeeder.php
<?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を以下のようにして、

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

そしてモデルを以下のように変更します。

Person.php
<?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

としたのち、コントローラーを以下の用に編集します。

PersonController.php
<?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`に
config/app.php
'faker_locale'=>'ja_JP'

を追記してください!
多分キャッシュが残っているのでターミナルで

php artisan config:cache

を忘れずに。

参考にさせていただいた記事・関連記事

[Instant Search with Laravel Scout & Algolia](https://qiita.com/avosalmon/items/b7b90c734709093fb927) [Nuxt.js+Algoliaで全文検索可能なタスク管理アプリを実装するハンズオン!](https://qiita.com/mido_app/items/919839aaf33382d9bc89)
5
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?