elasticsearch,tire,Ruby On Rails,Ruby On Rails 3,Rspec,elasticsearch,Tire" /> elasticsearch,tire,Ruby On Rails,Ruby On Rails 3,Rspec,elasticsearch,Tire" />

Ruby on rails 如何在Rails应用程序(Rspec)中测试ElasticSearch

Ruby on rails 如何在Rails应用程序(Rspec)中测试ElasticSearch,ruby-on-rails,ruby-on-rails-3,rspec,elasticsearch,tire,Ruby On Rails,Ruby On Rails 3,Rspec,elasticsearch,Tire,我想知道在使用ElasticSearch和Tire时,您是如何在应用程序中测试搜索的 如何设置新的ElasticSearch测试实例?有办法嘲笑它吗 你知道有什么宝石可以帮你吗 我发现一些有用的东西: 我发现一篇很好的文章几乎回答了我所有的问题:) 另外,轮胎作者卡米也给出了答案 这也很有用: 我不敢相信我在询问之前没有找到这些…为当前环境的索引名添加前缀 您可以为每个环境设置不同的索引名(在您的示例中为测试环境) 例如,您可以在中创建初始值设定项 config/initializers

我想知道在使用ElasticSearch和Tire时,您是如何在应用程序中测试搜索的

  • 如何设置新的ElasticSearch测试实例?有办法嘲笑它吗

  • 你知道有什么宝石可以帮你吗


我发现一些有用的东西:

我发现一篇很好的文章几乎回答了我所有的问题:)

另外,轮胎作者卡米也给出了答案

这也很有用:

我不敢相信我在询问之前没有找到这些…

为当前环境的索引名添加前缀 您可以为每个环境设置不同的索引名(在您的示例中为测试环境)

例如,您可以在中创建初始值设定项

config/initializers/tire.rb
使用以下行:

Tire::Model::Search.index_prefix "#{Rails.application.class.parent_name.downcase}_#{Rails.env.to_s.downcase}"
删除索引的一种可行方法 假设您有名为Customer、Order和Product的模型,将以下代码放在测试启动/before块/each run块的某处

# 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
可供替代的 另一种方法是设置一个不同的ElasticSearch实例,以便在另一个端口(比如1234)上进行测试。 在您的环境/test.rb中,您可以设置

Tire::Configuration.url "http://localhost:1234"
然后,在适当的位置(例如,您的测试启动),您可以使用以下命令删除ElasticSearch测试实例上的所有索引:

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

也许您仍然必须确保模型类的轮胎映射定义仍然被调用

我在rspec套件中通过tire删除elasticsearch索引时遇到了一个奇怪的错误。在我的Rspec配置中,类似于Bits和Bytes博客,我有一个after_每次调用,它清理数据库并清除索引

我发现我需要调用Tire的create_elasticsearch_index方法,该方法负责读取ActiveRecord类中的映射,以设置适当的分析器等。我看到的问题是我有一些:在我的模型中,没有分析实际被分析的字段(这打破了我希望刻面的工作方式)

在dev上一切都很好,但是测试套件失败了,因为facet被单个单词而不是整个多单词字符串分解。在删除索引后,似乎没有在rspec中正确创建映射配置。添加create_elasticsearch_index调用修复了以下问题:

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

媒体是我的模范课程。

我遇到了类似的问题,下面是我如何解决的。请记住,我的解决方案建立在@spaudanjo解决方案之上。因为我使用的是spork,所以我将其添加到
spec\u helper.rb
spork.each\u run
块中,但您可以将其添加到任何其他each/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
它基本上为每个测试用例定义了自己的唯一前缀,这样就没有索引了。其他解决方案都遇到了一个问题,即即使在删除索引之后,弹性搜索也不会刷新索引(即使在运行
Model.index.refresh
)这就是随机前缀存在的原因

它还加载每个模型,并检查它是否响应
轮胎
,这样我们就不需要在
spec_helper.rb
和其他区域中维护响应轮胎的所有模型的列表

由于此方法在使用后不会“删除”索引,因此您必须定期手动删除它。虽然我不认为这是一个大问题,但您可以使用以下命令删除:

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


要查找
YOURRAILSNAMEHERE
是什么,请运行
rails控制台
并运行
rails.application.class.parent\u name.downcase
。输出将是您的项目名称。

这是个好主意,我会试试,谢谢。您是否有特定的设置来清除每次测试的索引?谢谢您的更新。我想知道测试会变得多慢。。。我想我必须尝试一下。请告诉我们这是否会是一个巨大的性能问题(我想你可能是对的:-)。在我做了任何这些之后,我再也不会得到任何搜索结果。如果能够删除文档本身而不是整个索引,那就太好了。这样,您就不需要重新加载模型或任何东西。顺便说一句,要运行另一个ES实例,请使用类似于
elasticsearch-f-Des.http.port=9400-9500-Des.cluster.name=testing的东西。如果您不指定集群名称,它将自动加入原始服务器的集群,并且您仍将写入开发环境索引。