お世話になっております。今回はlaravelプロジェクトに置いてElasticsearchを導入しようとしています。
ElasticSearchに関しては完全に初心者です。
下の記事を参考にLaravel上で動くか実験中です。
【Laravel】Laravel Scout + Elasticsearchを使った全文検索の実装方法
環境
- Laradock
- PHP 7.2
- laravel 5.7.2
- ElasticSearch 6.6
- mysql 5.5
立ち上げているドッカーコンテナ
- nginx
- php-fpm
- elasticsearch
- mysql
状況
上記の記事と異なる点として、Dockerのworkspaceからlaravelを扱っている所がありエラー部分がいくつか出ましたが、Host名を調整することで動いています。
また、ElasticSearchEngineの部分でflushメソッドがないというエラーが出た為、下の空メソッドを追加して動かしています。
public function flush($models){}
データも正常に入り、記事の'登録済みのデータを取得する'のところで下のコマンドを実行すると記事と同様にデータが出力される状態です。
登録済みのデータを取得する
// 全取得
$ curl -H "Content-Type:application/json" -X GET elasticsearch:9200/scout/_search -d '{"query":{"match_all":{}}}'
// 検索
$ curl -H "Content-Type:application/json" -X GET "elasticsearch:9200/scout/_search" -d {\"query\":{\"match\":{\"id\":3}}}
問題
記事の'リクエストパラメータを使って検索してみる'を行おうとしたところデータが一つもブラウザ上に表示されず困っています。
リクエストパラメータを使って検索してみる
Route::get('/post/search', function () {
return App\Models\Post::search(\request('q'))->paginate();
});
http://localhost/post/search?q=1などクエリを入れてアクセスしても以下のようにdataが入らない状態です。
# 整形してあります
{
"current_page": 1,
"data": [],
"first_page_url": "http:\/\/localhost\/post\/search?query=&page=1",
"from": null,
"last_page": 1,
"last_page_url": "http:\/\/localhost\/post\/search?query=&page=1",
"next_page_url": null,
"path": "http:\/\/localhost\/post\/search",
"per_page": 15,
"prev_page_url": null,
"to": null,
"total": 0
}
curlでは正常に検索も行えていますが、laravelを使って表示が上手くいきません。どこが問題かも検討が付かず困っています。ご教授よろしくお願い致します。
追記
ElasticSearcEngin
/**
* Perform the given search on the engine.
*
* @param \Laravel\Scout\Builder $builder
* @return mixed
*/
public function search(Builder $builder)
{
return $this->performSearch($builder, array_filter([
'filters' => $this->filters($builder),
'limit' => $builder->limit,
]));
}
/**
* @param \Laravel\Scout\Builder $builder
* @param array $options
* @return array|mixed
*/
protected function performSearch(Builder $builder, $options = [])
{
$params = [
'index' => $this->index,
'type' => $builder->index ?: $builder->model->searchableAs(),
'body' => [
'query' => [
'bool' => [
'must' => [
'term' => [
'title' => "{$builder->query}",
]
],
],
],
]
];
if ($sort = $this->sort($builder)) {
$params['body']['sort'] = $sort;
}
if (isset($options['filters']) && count($options['filters'])) {
$params['body']['query']['bool']['filter'] = $options['filters'];
}
if ($builder->callback) {
return call_user_func(
$builder->callback,
$this->elastic,
$builder->query,
$params
);
}
return $this->elastic->search($params);
}
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
+1
自分も同じ記事を参考に少し触った程度なのであっているかわかりませんが・・・
①カスタムエンジンのperformSearch部分のクエリが正しいか
②DB自体にデータが入っているのか(記事はsqliteでしたが自分はMysqlにデータをいれてました)
を確認されたらいいのかなと
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
+1
performSearch部分のクエリを
$params = [
'index' => $this->index,
'type' => $builder->index ?: $builder->model->searchableAs(),
'body' => [
'query' => [
'bool' => [
'must' => [
[
'query_string' => [
'query' => "{$builder->query}"
]
]
]
]
]
]
];
こんな感じにするとtitle以外も検索対象になるはずです
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
check解決した方法
0
検索の時に大文字入りの検索ワードは引っかからないようです。
'Alias in DDD'のような文があったとき、クエリーとして引っかかるものは'alias','in','ddd'のようです。
modelのsearchへ飛ばす前に小文字に変換する処理を書くことで大文字入りでも検索できるようにしました。
Route::get('/post/search', function () {
$query = mb_strtolower(\request('q'));
return App\Models\Post::search($query)->paginate();
});
いまだに数字の検索はうまくいっておりません。ここからはESの分野だと思うのでもう少し探ってみようと思います。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.11%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
質問への追記・修正、ベストアンサー選択の依頼
asahina1979
2019/06/17 18:58
まずは記事とすべてバージョンを合わせて試してください。