この記事では、Ruby on Rails と Elasticsearch を使用して全文検索を実装する方法を説明します。今日では、誰もが検索語を入力すると、その検索語に対する候補や強調表示された結果が表示されることに慣れています。 Google や Facebook などのサイトで見られるように、オートコレクトは、検索しようとしているもののスペルが間違っている場合にも便利な機能です。
MySQL や Postgres などのリレーショナル データベースだけを使用してこの機能をすべて実現するのは簡単ではありません。そこで、Elasticsearch を使用します。これは、検索専用に構築され最適化されたデータベースと考えることができます。これはオープンソースであり、Apache Lucene 上に構築されています。
Elasticsearch の最も優れた機能の 1 つは、REST API を使用してその機能を公開することです。そのため、ほとんどのプログラミング言語に対してこの機能をカプセル化するライブラリがあります。
先ほど、Elasticsearch は検索用のデータベースのようなものであると述べました。これは、いくつかの用語に精通している場合に役立ちます。
ここで注意すべき点の 1 つは、Elasticsearch では、ドキュメントをインデックスに書き込むときに、ドキュメントのフィールドが文字通り分析され、検索が簡単かつ高速になるということです。 Elasticsearch は地理位置情報もサポートしているため、特定の場所から一定の距離内にあるドキュメントを検索できます。これはまさに Foursquare が検索を実装する方法です。
Elasticsearch は高いスケーラビリティを念頭に置いて構築されているため、複数のサーバーでクラスターを構築するのが簡単で、一部のサーバーに障害が発生した場合でも高可用性を実現できることを述べておきたいと思います。この記事では、さまざまな種類のクラスターを計画および展開する方法については詳しく説明しません。
Linux を使用している場合は、いずれかのリポジトリから Elasticsearch をインストールできる場合があります。 APTとYUMで使用できます。
Mac を使用している場合は、Homebrew を使用してインストールできます: brew install elasticsearch
。 elasticsearch をインストールすると、ターミナルに関連フォルダーのリストが表示されます:
インストールが適切に動作していることを確認するには、ターミナルに elasticsearch
と入力してインストールを開始します。次に、ターミナルで curl localhost:9200
を実行すると、次のような内容が表示されるはずです。
/usr/local/Cellar/elasticsearch/2.2.0_1/libexec/bin/plugin -install royrusso/elasticsearch-HQ
インストールが完了したら、ブラウザで http://localhost:9200/_plugin/hq に移動します:
[
Connect] をクリックすると、クラスターのステータスを示す画面が表示されます: p>
この時点では、ご想像のとおり、インデックスやドキュメントはまだ作成されていませんが、Elasticsearch のローカル インスタンスがインストールされ、実行されています。Rails アプリケーションの作成
rails 新しい elasticsearch-rails
rails はスキャフォールディング記事のタイトル:文字列テキスト:テキストを生成します
次に、デフォルトで記事リストを表示できるように、新しいルート ルートを追加する必要があります。
config/routes.rb: を編集しますリーリー
コマンド rake db:merge
を実行してデータベースを作成します。 rails サーバー
を起動する場合は、ブラウザを開いて localhost:3000 に移動し、いくつかの記事をデータベースに追加するか、作成したダミー データを含むファイル db/seeds.rb をダウンロードしてください。フォームに記入するのに多くの時間を費やさなければなりません。
これで、データベース内の記事を含む小さな Rails アプリケーションが完成したので、検索機能を追加する準備が整いました。まず、2 つの公式 Elasticsearch Gem への参照を追加します:
リーリー多くの Web サイトでは、すべてのページのトップ メニューに検索用のテキスト ボックスがあるのが一般的です。そこで、app/views/search/_form.html.erb にフォーム セクションを作成します。 ご覧のとおり、生成されたフォームを GET を使用して送信しているため、特定の検索の URL を簡単にコピーして貼り付けることができます。
リーリーメイン サイト レイアウトのフォームへの参照を追加します。 app/views/layouts/application.html.erb を編集します。
リーリー実際の検索を実行して結果を表示するためのコントローラーも必要なので、コマンド rails g newcontroller Search
を実行してコントローラーを生成します。
ご覧のとおり、Article モデルでメソッド search
を呼び出しています。まだ定義していないため、この時点で検索を実行しようとするとエラーが発生します。また、SearchController のルートを config/routes.rb ファイルに追加していないので、これを追加しましょう:
gem 'elasticsearch-rails' のドキュメントを見ると、Elasticsearch でインデックスを作成するモデルに 2 つのモジュール (この場合は article.rb##) を含める必要があります。 #. リーリー
最初のモデルは、前のコントローラーで使用した Search メソッドを挿入します。 2 番目のモジュールは、ActiveRecord コールバックと統合して、データベースに保存する記事の各インスタンスにインデックスを付けます。また、データベースから記事を変更または削除すると、インデックスも更新されます。したがって、それは私たちにとってすべて透明です。以前にデータをデータベースにインポートした場合、これらの記事はまだ Elasticsearch インデックスに含まれていないため、新しい記事のみが自動的にインデックス付けされます。したがって、手動でインデックスを付ける必要がありますが、
rails console を起動すれば簡単です。次に、
irb(main) > Article.import を実行するだけです。
検索ハイライト
app/models/article.rbを編集し、デフォルトの検索方法を変更します: リーリー
デフォルトでは、search メソッドは gem 'elasticsearch-models' によって定義され、Elasticsearch API のラッパー クラスにアクセスするためのプロキシ オブジェクト __elasticsearch__ を提供します。したがって、ドキュメントで提供されている標準の JSON オプションを使用して、デフォルトのクエリを変更できます。
app/views/search/search.html.erb を編集します。 リーリー
強調表示されたタグの CSS スタイルをapp/assets/stylesheets/search.scss に追加します: リーリー
「ruby」をもう一度検索してみてください:ご覧のとおり、検索語を強調表示するのは簡単ですが、JSON クエリを送信する必要があり、Elasticsearch のドキュメントで指定されているように、いかなる種類の抽象化も行っていないため、理想的ではありません。 。
サーチキックジェム
gem 'searchkick' を gemfile に追加します。変更する必要がある最初のクラスは Article.rb モデルです:
リーリー
rake searchkick:reindex CLASS=Article を実行する必要があります。検索語を強調表示するには、
search_controller.rb から追加のパラメーターを検索メソッドに渡す必要があります。
リーリー
views/search/search.html.erb です。これは、searchkick が別の形式で結果を返すようになったためです。 リーリー
今度は、アプリケーションを再度実行して、検索機能をテストします:
请注意,我输入了搜索词“dato”。我这样做的目的是为了向您展示,默认情况下,searchkick 设置为分析索引的文本,并且更允许拼写错误。
自动建议或预先输入可预测用户将输入的内容,从而使搜索体验更快、更轻松。请记住,除非您有数千条记录,否则最好在客户端进行过滤。
让我们首先添加 typeahead 插件,该插件可通过 gem 'bootstrap-typeahead-rails'
获得,并将其添加到您的 Gemfile 中。接下来,我们需要向 app/assets/javascripts/application.js 添加一些 JavaScript,以便当您开始在搜索框中输入内容时,会出现一些建议。
//= require jquery //= require jquery_ujs //= require turbolinks //= require bootstrap-typeahead-rails //= require_tree . var ready = function() { var engine = new Bloodhound({ datumTokenizer: function(d) { console.log(d); return Bloodhound.tokenizers.whitespace(d.title); }, queryTokenizer: Bloodhound.tokenizers.whitespace, remote: { url: '../search/typeahead/%QUERY' } }); var promise = engine.initialize(); promise .done(function() { console.log('success'); }) .fail(function() { console.log('error') }); $("#term").typeahead(null, { name: "article", displayKey: "title", source: engine.ttAdapter() }) }; $(document).ready(ready); $(document).on('page:load', ready);
关于前一个片段的一些评论。在最后两行中,因为我没有禁用涡轮链接,所以这是连接我想要在页面加载时运行的代码的方法。在脚本的第一部分,您可以看到我正在使用 Bloodhound。它是 typeahead.js 建议引擎,我还设置了 JSON 端点来发出 AJAX 请求来获取建议。之后,我在引擎上调用 initialize()
,并使用其 id“term”在搜索文本字段上设置预输入。
现在,我们需要对建议进行后端实现,让我们从添加路由开始,编辑 app/config/routes.rb。
Rails.application.routes.draw do root to: 'articles#index' resources :articles get "search", to: "search#search" get 'search/typeahead/:term' => 'search#typeahead' end
接下来,我将在 app/controllers/search_controller.rb 上添加实现。
def typeahead render json: Article.search(params[:term], { fields: ["title"], limit: 10, load: false, misspellings: {below: 5}, }).map do |article| { title: article.title, value: article.id } end end
此方法返回使用 JSON 输入的术语的搜索结果。我只按标题搜索,但我也可以指定文章的正文。我还将搜索结果的数量限制为最多 10 个。
现在我们准备尝试 typeahead 实现:
如您所见,将 Elasticsearch 与 Rails 结合使用使搜索数据变得非常简单且快速。在这里,我向您展示了如何使用 Elasticsearch 提供的低级 gem,以及 Searchkick gem,这是一个隐藏了 Elasticsearch 工作原理的一些细节的抽象。
根据您的具体需求,您可能会很乐意使用 Searchkick 并快速轻松地实施全文搜索。另一方面,如果您有一些其他复杂的查询,包括过滤器或组,您可能需要了解有关 Elasticsearch 上查询语言的详细信息,并最终使用较低级别的 gem 'elasticsearch-models' 和 'elasticsearch-导轨”。
以上がElasticsearchを使用したRailsでの全文検索の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。