6
votes

I want to use ElasticSearch + Tire to search stored in MongoDB.

However, I'm getting the following error when I try to perform a search:

Tire::Search::SearchRequestFailed in SearchController#index

404 : {"error":"IndexMissingException[[events] missing]","status":404}

From what I understand, this tells me that the indexes are missing for the Event, even though I've told it to generate them when I ran db:setup.

Model:

class Event
  include Mongoid::Document
  include Mongoid::Timestamps 

  include Tire::Model::Search
  include Tire::Model::Callbacks

  field :name, :type => String
  field :description, :type => String
  field :started_at => Time
  field :ended_at => Time

  def to_indexed_json
    self.as_json
  end
end

Controller:

  def search
    Event.tire.search(params[:q])
  end

Any ideas on how to resolve this please?

5
Please update the model -- I don't see any field definitions there. All in all, when you load the app, the should be created, unless it already exists.karmi
@karmi: I've added fields to the model now.gabriel
I've realized that the issue was that the model was not getting added to the ElasticSearch index when it was saved. I've tried manually adding / importing it, but I can't seem to get it to work… Any help in resolving this would be greatly appreciated.gabriel

5 Answers

12
votes

... or even better, just run :

rake environment tire:import CLASS=Event FORCE=true
3
votes

Set an Initializer ( the following will work locally on your machine and on heroku with bonsai add-on too, just in case ... ):

# config/initializers/bonsai.rb

if ENV['BONSAI_INDEX_URL']
  Tire.configure do
    url "http://index.bonsai.io"
  end
  BONSAI_INDEX_NAME = ENV['BONSAI_INDEX_URL'][/[^\/]+$/]
else
  app_name = Rails.application.class.parent_name.underscore.dasherize
  BONSAI_INDEX_NAME = "#{app_name}-#{Rails.env}"
end

In your model add the index_name :

class Event
  include Mongoid::Document
  include Mongoid::Timestamps 

  include Tire::Model::Search
  include Tire::Model::Callbacks

  index_name BONSAI_INDEX_NAME

  field :name, :type => String
  field :description, :type => String
  field :started_at => Time
  field :ended_at => Time

  def to_indexed_json
    self.as_json
  end
end

Then open your Rails console with rails c and run :

1.9.2p290 :001 >Event.create_elasticsearch_index
 => 200 : {"ok":true,"acknowledged":true} 
1.9.2p290 :002 > Tire.index BONSAI_INDEX_NAME
1.9.2p290 :003 >        import Event.all
1.9.2p290 :004?>   refresh
1.9.2p290 :005?> end

You should see something similar :

MONGODB (0ms) ... ['system.namespaces'].find({})
MONGODB (0ms) ... ['events'].find({})
 => #<Tire::Index:0xca8fb18 @name="your-app-name-development",@response=200 : {"ok":true,"_shards":{"total":10,"successful":5,"failed":0}}> 
1.9.2p290 :006 > 

Now start rails and re-try.

1
votes

... see also :

Event.index.import Event.all

This way all your records are loaded into memory, serialized into JSON, and sent down the wire to ElasticSearch. This, as well as the two solutions before, should evoid "IndexMissingException[[events] missing]" error.

1
votes

This can happen if you modify the configuration. Try removing the Tire.configure if you define one.

0
votes

Have you indexed your Event model ? And your Venues model ? Elastic search is also looking for the Venues index

I have a rake task to reindex my Models

desc "Reindex event"
task :reindex_events => :environment do

batch_size = 1000
count = batch_size

Event.all.find_in_batches(:batch_size => batch_size) { |objects|

  puts "Count: " + count.to_s
  count += batch_size

  Event.index.import objects
}    

end