-d オプションを指定する。
1 |
$ mysqldump -u user dbname -d test.sql |
最近はウェブ系アプリ中心、あとWindowsアプリちょっと
-d オプションを指定する。
1 |
$ mysqldump -u user dbname -d test.sql |
デフォルトだとSearchableなModelの全カラムがインデックスされる。
インデックスしたくないカラムがある場合はSearchableのtoSearchableArray()を上書きして、リターンされる配列からそのカラムのデータを除外すれば良いらしい。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
namespace App; use Illuminate\Database\Eloquent\Model; use Laravel\Scout\Searchable; class Article extends Model { use Searchable; /** * Get the indexable data array for the model. * * @return array */ public function toSearchableArray() { $array = $this->toArray(); // Customize array... unset($array['id']); unset($array['image1']); unset($array['image2']); unset($array['image3']); unset($array['published_on']); unset($array['created_at']); unset($array['updated_at']); return $array; } protected $fillable = ['image1', 'image2', 'image3', 'title', 'description', 'published_on']; protected $dates = ['published_on']; } |
Laravel Scout – Laravel – The PHP Framework For Web Artisans
https://laravel.com/docs/5.4/scout#configuration
Kuromojiは日本語の形態素解析ライブラリ。これ無しだと、日本語が分かち書きされない状態でインデックス化されてしまうので、日本語の単語で全文しようとしてもうまくヒットしないのだろうと想像する。
Kuromojiに関しては以下の説明が明るい。
Elasticsearchを日本語で使う設定のまとめ – Qiita
http://qiita.com/shin_hayata/items/41c07923dbf58f13eec4
kuromoji – japanese morphological analyzer
http://www.atilika.org/
Japanese (kuromoji) Analysis Plugin | Elasticsearch Plugins and Integrations [5.5] | Elastic
https://www.elastic.co/guide/en/elasticsearch/plugins/current/analysis-kuromoji.html
ElasticSearch同梱のユーティリティを使ってインストールする。
1 2 3 |
$ cd /usr/share/elasticsearch $ sudo bin/elasticsearch-plugin install analysis-kuromoji $ sudo bin/elasticsearch-plugin install analysis-icu |
公式サイトを眺めてみたんだけど、はっきりと「設定はコレ」みたいな記事がない。
以下の記事がちょっと古いんだけど設定ファイルの記述があったのでなぞってみる。
Elasticsearch に kuromoji を入れて日本語全文検索をする – Qiita
http://qiita.com/mserizawa/items/8335d39cacb87f12b678
1 2 3 |
$ vi config/elasticsearch.yml index.analysis.analyzer.default.type: custom index.analysis.analyzer.default.tokenizer: kuromoji_tokenizer |
設定ファイル編集してElasticSeachを再起動したらログにエラーが出た。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
************************************************************************************* Found index level settings on node level configuration. Since elasticsearch 5.x index level settings can NOT be set on the nodes configuration like the elasticsearch.yaml, in system properties or command line arguments.In order to upgrade all indices the settings must be updated via the /${index}/_settings API. Unless all settings are dynamic all indices must be closed in order to apply the upgradeIndices created in the future should use index templates to set default values. Please ensure all required values are updated on all indices by executing: curl -XPUT 'http://localhost:9200/_all/_settings?preserve_existing=true' -d '{ "index.analysis.analyzer.default.tokenizer" : "kuromoji_tokenizer", "index.analysis.analyzer.default.type" : "custom" }' ************************************************************************************* |
API経由でインデックスごとに設定しろということらしい。
インデックスの変更前にはインデックスを一旦クローズする必要がある。そして設定を変更してから、インデックスを再度オープンすることで、新しい設定でインデックスが使えるようになる。これ少しハマったので以下記事を覚書リンク。
elasticsearch – error when trying to update the settings – Stack Overflow
https://stackoverflow.com/questions/19758335/error-when-trying-to-update-the-settings
1 2 3 4 5 6 |
$ curl -XPOST 'localhost:9200/scout/_close' $ curl -XPUT 'http://localhost:9200/scout/_settings?preserve_existing=true' -d '{ "index.analysis.analyzer.default.tokenizer" : "kuromoji_tokenizer", "index.analysis.analyzer.default.type" : "custom" }' $ curl -XPOST 'localhost:9200/scout/_open' |
これで設定が変わったので、古い設定のまま作成されているインデックスをいったん削除する。
1 |
$ curl -X DELETE http://localhost:9200/scout |
再び記事をElasticSearchに流し込む。
1 |
$ php artisan scout:import "App\Article" |
インデックスのサイズを比べてみる。Kuromoji追加前のインデックスは記事12件で183KB。
1 2 3 |
$ curl -X GET http://localhost:9200/_cat/indices?v health status index uuid pri rep docs.count docs.deleted store.size pri.store.size yellow open scout PN7wNd5iRga8pqmc9nj0VA 5 1 12 0 183kb 183kb |
Kuromoji追加後のインデックスは記事12件で292.9KB。
1 2 3 |
$ curl -X GET http://localhost:9200/_cat/indices?v health status index uuid pri rep docs.count docs.deleted store.size pri.store.size yellow open scout PN7wNd5iRga8pqmc9nj0VA 5 1 12 0 292.9kb 292.9kb |
形態素解析により日本語が分かち書きされてインデックスされた結果だろう。
日本語の単語で検索したら今度はちゃんとヒットした。良さげ。
ElasticSearchのセットアップができたので、ここからはLaravel側のセットアップ。
Laravel Scout – Laravel – The PHP Framework For Web Artisans
https://laravel.com/docs/5.4/scout
Laravel Scout Elasticsearch Driver
https://github.com/ErickTamayo/laravel-scout-elastic
1 2 3 4 5 6 7 8 9 |
$ composer require laravel/scout $ composer require tamayo/laravel-scout-elastic $ composer require elasticsearch/elasticsearch $ vi config/app.php Laravel\Scout\ScoutServiceProvider::class, ScoutEngines\Elasticsearch\ElasticsearchProvider::class, $ php artisan vendor:publish --provider="Laravel\Scout\ScoutServiceProvider" |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
$ vi app/Article.php <?php namespace App; use Illuminate\Database\Eloquent\Model; use Laravel\Scout\Searchable; class Article extends Model { use Searchable; protected $fillable = ['title', 'description', 'tags', 'published_on']; protected $dates = ['published_on']; } |
1 2 3 4 5 6 7 8 9 10 11 12 |
$ vi config/scout.php //'driver' => env('SCOUT_DRIVER', 'algolia'), 'driver' => env('SCOUT_DRIVER', 'elasticsearch'), 'elasticsearch' => [ 'index' => env('ELASTICSEARCH_INDEX', 'laravel'), 'config' => [ 'hosts' => [ env('ELASTICSEARCH_HOST', 'localhost'), ], ], ], |
1 2 3 |
$ vi .env ELASTICSEARCH_INDEX=scout ELASTICSEARCH_HOST=http://localhost:9200 |
これでセットアップは完了。
公式ドキュメントで説明されている通り、Laravel Scoutを組み込んだ状態だと、Eloquentでレコード追加/更新/削除を行うとElasticSearchも併せて更新されるようになる。しかし、ElasticSearch組み込み時点で既に存在するレコードは手動でElasticSearchに流し込まないといけない。
というわけで、既存レコードをElasticSearchに流し込む。
1 2 3 |
$ php artisan scout:import "App\Article" Imported [App\Article] models up to ID: 12 All [App\Article] records have been imported. |
ElasticSearchのインデックスを確認。
1 2 3 |
$ curl -X GET http://localhost:9200/_cat/indices?v health status index uuid pri rep docs.count docs.deleted store.size pri.store.size yellow open scout PN7wNd5iRga8pqmc9nj0VA 5 1 12 0 292.9kb 292.9kb |
コントローラから検索してみる
1 |
$articles = Article::search($str)->get(); |
記事本文に含まれる日本語の単語を入れてみると、検索されるものあり、されないものあり。どうも挙動がおかしい。おそらく日本語の処理が上手くいっていないのだろう。
Kuromojiのセットアップへ続く。
Laravel Scoultは、Laravelにフルテキスト検索機能を追加するパッケージ。
Laravel Scout – Laravel – The PHP Framework For Web Artisans
https://laravel.com/docs/5.4/scout
その検索エンジンにはデフォルトでAlgoliaが選ばれている。
Algolia | The Most Reliable Platform for Building Search
https://www.algolia.com/
AlgoliaはサーチAPIを提供する商用サービス。無償プランもあるけど、レコード上限は1万件、オペレーション上限は月間10万件に制限されている。自分が今やっている実験ではレコード件数がすでに6万件を超えているので無償プランは使えない。かといって、自腹で有償プランを契約できる予算は無い。
Laravel Scoutはドライバを書くことで異なる検索エンジンを接続できるようになっている。オープンソースのフルテキスト検索エンジンと言えばElasticSearch。調べてみると、Laravel ScoultのElastric Searchドライバがすでに存在した。
Laravel Scout Elasticsearch Driver
https://github.com/ErickTamayo/laravel-scout-elastic
セットアップ手順を説明している記事も見つかった。
Basic Search Functionality with ElasticSearch & Laravel Scout
https://medium.com/@samogorm/basic-search-functionality-with-elasticsearch-laravel-scout-6ac182c99cbf
この記事をなぞって、自分のLaravelプロジェクトにElasticSearch+Laravel Scoutによる全文検索機能を追加してみたい。いきなり本番サーバーに適用するのは怖いので、ローカルのHomestead(Ubuntu)で試してみる。
まずは以下の下準備を行う。
Prerequisites
Linuxmania:apt-getでJavaをインストールしよう (Ubuntu)
https://www.linuxmania.jp/apt-install-java.html
1 2 3 4 5 6 |
$ sudo apt-get update $ sudo apt-get install default-jre $ java -version openjdk version "1.8.0_131" OpenJDK Runtime Environment (build 1.8.0_131-8u131-b11-0ubuntu1.16.04.2-b11) OpenJDK 64-Bit Server VM (build 25.131-b11, mixed mode) |
Installing Elasticsearch | Elasticsearch Reference [5.5] | Elastic
https://www.elastic.co/guide/en/elasticsearch/reference/current/install-elasticsearch.html
1 2 3 4 5 |
$ wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add - $ sudo apt-get install apt-transport-https $ echo "deb https://artifacts.elastic.co/packages/5.x/apt stable main" | sudo tee -a /etc/apt/sources.list.d/elastic-5.x.list $ sudo apt-get update $ sudo apt-get install elasticsearch |
1 2 |
$ sudo /etc/init.d/elasticsearch start [ ok ] Starting elasticsearch (via systemctl): elasticsearch.service. |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
$ curl http://localhost:9200 { "name" : "zbu9NHN", "cluster_name" : "elasticsearch", "cluster_uuid" : "VVI6hazgQB2dssfD3kQQeQ", "version" : { "number" : "5.5.0", "build_hash" : "260387d", "build_date" : "2017-06-30T23:16:05.735Z", "build_snapshot" : false, "lucene_version" : "6.6.0" }, "tagline" : "You Know, for Search" } |
ElasticSearchが動いたので、Laravel Scoutの組み込みに続く。
サーバーサイドでクローンを使っていくつかのサイトを定期的にスクレイピングしているのだけど、新たに追加するサイトがAngularJSで書かれているようで、file_get_contents関数などではHTMLを取得できないことがわかった。さてどうするか。
ヘッドレスブラウザのPhantomJSを使えば、JavaScriptでレンダリングされた結果のHTMLをサーバーサイドでも取得できそうだ。PHP PhantomJSというPHPのインタフェースも公開されているようなので、LaravelのCommandとして実装してみる。
PhantomJS | PhantomJS
http://phantomjs.org/
Linux 64-bitをダウンロードして bin ディレクトリに格納。
1 2 3 |
$ curl -L -O https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2 $ tar jxf phantomjs-2.1.1-linux-x86_64.tar.bz2 $ cp -p phantomjs-2.1.1-linux-x86_64/bin/phantomjs bin/phantomjs |
1 2 |
$ bin/phantomjs phantomjs> ←プロンプトが表示されればOK |
1 |
$ composer require "jonnyw/php-phantomjs:4.*" |
以下のサイトのサンプルを拝借してテスト。
PHP PhantomJS を使ってPHPでヘッドレスブラウジング | QUARTETCOM TECH BLOG
http://tech.quartetcom.co.jp/2016/04/07/php-phantomjs/
1 2 3 4 5 6 7 8 9 10 11 |
use JonnyW\PhantomJs\Client; $client = Client::getInstance(); $request = $client->getMessageFactory()->createRequest(); $response = $client->getMessageFactory()->createResponse(); $url = 'file:///path/to/hello_phantomjs.html';$request->setUrl($url); $client->send($request, $response); echo $response->getContent(); |
Googleの新しい診断ツール。
モバイルサイトの読み込み速度とパフォーマンスをテストする – Google
https://testmysite.withgoogle.com/intl/ja-jp
新たなスピード診断ツール、Test my siteをGoogleが公開。遅さが原因の想定ユーザー離脱率は何%? | 海外SEO情報ブログ
https://www.suzukikenichi.com/blog/measuring-site-speed-by-test-my-site/
わかりやすくまとまっていたので覚書リンク。
もう迷わない!人気JavaScriptフレームワーク、ライブラリー、ツール総まとめ – WPJ
https://www.webprofessional.jp/top-javascript-frameworks-libraries-tools-use/
Response::download()を使う。
1 2 3 4 |
$pathToFile = '/path/to/file.csv'; $filename = 'test.csv'; $headers = ['Content-Type' => 'text/csv']; return Response::download($pathToFile , $filename, $headers); |
Response::make()を使う。
1 2 3 4 5 6 |
$filename = 'test.csv'; $headers = [ 'Content-Type' => 'text/csv', 'Content-Disposition' => 'attachment; filename="' . $filename . '"' ]; return Response::make($csv, 200, $headers); |
Laravelでファイルを生成せずにファイルダウンロード – ふたりはララベル (Laravel PHP Framework)
http://laravel.hatenablog.com/entry/2015/03/19/232748
Laravelでファイルダウンロード1 – ふたりはララベル (Laravel PHP Framework)
http://laravel.hatenablog.com/entry/2015/03/18/234506
HTTP Responses – Laravel – The PHP Framework For Web Artisans
https://laravel.com/docs/master/responses
ハマったので覚書。
以下の書き方だと該当レコードを全てgetしてしまうのでメモリ消費が大きい。
1 2 |
$count = Image::where('product_id', $product_id)->get()->count(); $count = $product->images->count(); |
以下の書き方だとSQLクエリーでcount(*)を取得するだけなので軽い。
1 2 |
$count = Image::where('product_id', $product_id)->count(); $count = $product->images()->count(); |
Eloquentでカウントするときの注意 – ララジャパン
http://www.larajapan.com/2016/06/19/eloquent%E3%81%A7%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88%E3%81%99%E3%82%8B%E3%81%A8%E3%81%8D%E3%81%AE%E6%B3%A8%E6%84%8F/