46

ElasticSearchとTireを使用しているときに、アプリケーションで検索をどのようにテストしていたのか疑問に思いました。

  • 新しいElasticSearchテストインスタンスをどのようにセットアップしますか?それをあざける方法はありますか?

  • あなたが知っている宝石はそれを助けるかもしれませんか?


私が役に立ったと思ったもの:

私は私の質問のほとんどすべてに答える素晴らしい記事を見つけました:)

http://bitsandbit.es/post/11295134047/unit-testing-with-tire-and-elastic-search#disqus_thread

さらに、タイヤの作者であるKarmiからの回答があります。

これも便利です:https ://github.com/karmi/tire/wiki/Integration-Testing-Rails-Models-with-Tire

尋ねる前にこれらを見つけられなかったなんて信じられない...

4

3 に答える 3

34

現在の環境のインデックス名のプレフィックス

環境(この場合はテスト環境)ごとに異なるインデックス名を設定できます。

たとえば、でイニシャライザを作成できます

config/initializers/tire.rb

次の行で:

Tire::Model::Search.index_prefix "#{Rails.application.class.parent_name.downcase}_#{Rails.env.to_s.downcase}"

インデックスを削除するための考えられるアプローチ

Customer、Order、Productという名前のモデルがあると仮定して、次のコードをtest-startup / before-block/each-run-blockのどこかに配置します。

# iterate over the model types
# there are also ways to fetch all model classes of the rails app automaticly, e.g.:
#   http://stackoverflow.com/questions/516579/is-there-a-way-to-get-a-collection-of-all-the-models-in-your-rails-app
[Customer, Order, Product].each do |klass|

  # make sure that the current model is using tire
  if klass.respond_to? :tire
    # delete the index for the current model
    klass.tire.index.delete

    # the mapping definition must get executed again. for that, we reload the model class.
    load File.expand_path("../../app/models/#{klass.name.downcase}.rb", __FILE__)

  end
end

別の方法として、別のポート、たとえば1234でテストするために別のElasticSearchインスタンスを設定することもできます。その後、enviornment/test.rbで設定できます。

Tire::Configuration.url "http://localhost:1234"

そして、適切な場所(テストのスタートアップなど)で、ElasticSearchテストのすべてのインデックスを削除できます-インスタンス:

Tire::Configuration.client.delete(Tire::Configuration.url)

モデルクラスのTire-Mapping定義がまだ呼び出されていることを確認する必要があるかもしれません。

于 2012-03-14T18:09:16.187 に答える
11

rspecスイートのtireを介してelasticsearchインデックスを削除すると、奇妙なバグが発生しました。私のRspec構成では、Bits and Bytesブログと同様に、データベースをクリーンアップしてインデックスを消去するafter_each呼び出しがあります。

ActiveRecordクラスのマッピングを読み取って適切なアナライザーなどを設定するTireのcreate_elasticsearch_indexメソッドを呼び出す必要があることがわかりました。私が見た問題は、実際に分析されているモデルにいくつかの:not_analyzedフィールドがあることでした(これは私がファセットを機能させたい方法を壊しました)。

開発ではすべて問題ありませんでしたが、ファセットが複数の単語の文字列全体ではなく個々の単語で分類されていたため、テストスイートは失敗していました。インデックスが削除された後、マッピング構成がrspecで適切に作成されていなかったようです。create_elasticsearch_index呼び出しを追加すると、問題が修正されました。

config.after(:each) do
  DatabaseCleaner.clean
  Media.tire.index.delete
  Media.tire.create_elasticsearch_index
end

メディアは私のモデルクラスです。

于 2012-05-04T15:27:42.303 に答える
4

私は同様の問題に遭遇しました、そしてこれが私がそれを解決した方法です。私のソリューションは@spaudanjoソリューションの上に構築されていることを忘れないでください。私はsporkを使用しているので、これをspec_helper.rb'sSpork.each_runブロック内に追加しますが、これを他の各/beforeブロックに追加することもできます。

# Define random prefix to prevent indexes from clashing
Tire::Model::Search.index_prefix "#{Rails.application.class.parent_name.downcase}_#{Rails.env.to_s.downcase}_#{rand(1000000)}"

# In order to know what all of the models are, we need to load all of them
Dir["#{Rails.root}/app/models/**/*.rb"].each do |model|
  load model
end

# Refresh Elastic Search indexes
# NOTE: relies on all app/models/**/*.rb to be loaded
models = ActiveRecord::Base.subclasses.collect { |type| type.name }.sort
models.each do |klass|
  # make sure that the current model is using tire
  if klass.respond_to? :tire
    # delete the index for the current model
    klass.tire.index.delete

    # the mapping definition must get executed again. for that, we reload the model class.
    load File.expand_path("../../app/models/#{klass.name.downcase}.rb", __FILE__)
  end
end

基本的に、インデックスに存在しないように、テストケースごとに独自のプレフィックスを定義します。他のソリューションはすべて、インデックスを削除した後でも、Elastic Searchが(実行した後でもModel.index.refresh)インデックスを更新しないという問題に悩まされていました。そのため、ランダム化されたプレフィックスがあります。

また、すべてのモデルをロードし、応答するかどうかをチェックするtireため、他の領域と他の領域の両方でタイヤに応答するすべてのモデルのリストを維持する必要がなくなりspec_helper.rbます。

このメソッドは、使用後にインデックスを「削除」しないため、定期的に手動で削除する必要があります。これが大きな問題になるとは思いませんが、次のコマンドで削除できます。

curl -XDELETE 'http://localhost:9200/YOURRAILSNAMEHERE_test_*/'

何であるかを見つけるにYOURRAILSNAMEHEREは、を実行rails consoleして実行しますRails.application.class.parent_name.downcase。出力はプロジェクトの名前になります。

于 2013-03-02T12:21:32.753 に答える