pat / thinking-sphinx

Sphinx/Manticore plugin for ActiveRecord/Rails
http://freelancing-gods.com/thinking-sphinx
MIT License
1.63k stars 468 forks source link

undefined method `sphinx_index_options' for Object:Class #348

Closed jaran closed 12 years ago

jaran commented 12 years ago

Hello we upgraded from sphinx 0.9.9 to sphinx 2.0.3 and thinking sphinx gem version 2.0.11. Now in a lot of our searches we get this error undefined method `sphinx_index_options' for Object:Class.

We cant narrow down where exactly its occuring and how to reproduce it everytime but it seems whenever we do search with the :classes options set it may error out.

Example search:

ThinkingSphinx.search( :classes => [News, Article], :order => 'release_at DESC', :limit => 20).all

News index


    define_index do
        indexes title, :prefix => true
    indexes [ author.first_name, author.last_name ], :as => :author
        indexes keywords, :prefix => true

        has created_at, :as => :created_at, :type => :datetime
        has release_at, :as => :release_at, :type => :datetime
    has total_weekly_views, :as => :viewed, :type => :integer
        has 'image_file_name IS NOT NULL', :as => :has_image, :type => :boolean
    has cpe
        has :id, :as => :news_id
        has author_id
        has place_in_news_tab

    where 'release_at <= UTC_TIMESTAMP()'

        set_property :field_weights => { 'title' => 1000, 'keywords' => 1000 }
    set_property :delta => :delayed
    end

Article index


  define_index do
    indexes title, :prefixes => true
    indexes keywords, :prefixes => true
    indexes teaser_html, body_html
    indexes [ author.first_name, author.last_name ], :as => :author
    indexes magazine(:type), :as => :magazine_type

    has created_at, :as => :created_at, :type => :datetime
    has magazine.publication_date, :as => :release_at, :type => :datetime
    has total_weekly_views, :as => :viewed, :type => :integer
    has place_in_news_tab
    has 'image_file_name IS NOT NULL', :as => :has_image, :type => :boolean
    has :id, :as => :article_id
    has "magazines.type = 'EuropeMagazine'", :type => :boolean, :as => :cpe
    has author_id

    where 'magazines.live = 1'

    set_property :field_weights => { 'title' => 500, 'keywords' => 70, 'teaser' => 50 }
    set_property :delta => :delayed
  end

Any insight into why this error would ever occur would be appreciated

pat commented 12 years ago

Nothing obvious comes to mind, but a stack trace would certainly help if you can get it to happen again.

jaran commented 12 years ago

ThinkingSphinx.search( :classes => [News, Article], :order => 'release_at DESC', :limit => 20).all Sphinx Query (210.0ms)
Sphinx Found 19868 results NoMethodError: undefined method sphinx_index_options' for Object:Class from /home/web/apps/cardplayer/shared/bundle/ruby/1.9.1/gems/thinking-sphinx-2.0.11/lib/thinking_sphinx/search.rb:885:ininstances_from_class' from /home/web/apps/cardplayer/shared/bundle/ruby/1.9.1/gems/thinking-sphinx-2.0.11/lib/thinking_sphinx/search.rb:927:in block in instances_from_matches' from /home/web/apps/cardplayer/shared/bundle/ruby/1.9.1/gems/thinking-sphinx-2.0.11/lib/thinking_sphinx/search.rb:925:ineach' from /home/web/apps/cardplayer/shared/bundle/ruby/1.9.1/gems/thinking-sphinx-2.0.11/lib/thinking_sphinx/search.rb:925:in instances_from_matches' from /home/web/apps/cardplayer/shared/bundle/ruby/1.9.1/gems/thinking-sphinx-2.0.11/lib/thinking_sphinx/search.rb:448:incompose_results' from /home/web/apps/cardplayer/shared/bundle/ruby/1.9.1/gems/thinking-sphinx-2.0.11/lib/thinking_sphinx/search.rb:438:in block in populate' from /home/web/apps/cardplayer/shared/bundle/ruby/1.9.1/gems/thinking-sphinx-2.0.11/lib/thinking_sphinx/search.rb:576:incall' from /home/web/apps/cardplayer/shared/bundle/ruby/1.9.1/gems/thinking-sphinx-2.0.11/lib/thinking_sphinx/search.rb:576:in retry_on_stale_index' from /home/web/apps/cardplayer/shared/bundle/ruby/1.9.1/gems/thinking-sphinx-2.0.11/lib/thinking_sphinx/search.rb:419:inpopulate' from /home/web/apps/cardplayer/shared/bundle/ruby/1.9.1/gems/thinking-sphinx-2.0.11/lib/thinking_sphinx/search.rb:105:in all' from (irb):48 from /home/web/apps/cardplayer/shared/bundle/ruby/1.9.1/gems/railties-3.2.2/lib/rails/commands/console.rb:47:instart' from /home/web/apps/cardplayer/shared/bundle/ruby/1.9.1/gems/railties-3.2.2/lib/rails/commands/console.rb:8:in start' from /home/web/apps/cardplayer/shared/bundle/ruby/1.9.1/gems/railties-3.2.2/lib/rails/commands.rb:41:in<top (required)>' from script/rails:6:in require' from script/rails:6:in

'

hemang commented 12 years ago

I am experiencing a similar error. Here's what I have found so far:

In results[:matches] the crc attribute is missing for one of the two results. In particular, the sphinx_internal_class attribute is missing but the class_crc is present. This would explain why the error happens in the upgrade to 2.0.11 based on the crc_attribute method's definition below

def crc_attribute Riddle.loaded_version.to_i < 2 ? 'class_crc' : 'sphinx_internal_class' end

As the crc is empty, class_from_crc(crc) returns an empty string here:

def instances_from_matches return single_class_results if one_class

  groups = results[:matches].group_by { |match|
    match[:attributes][crc_attribute]
  }
  groups.each do |crc, group|
    group.replace(
      instances_from_class(class_from_crc(crc), group)
    )
  end

And, this in turn causes this to throw an undefined method error:

def instances_from_class(klass, matches) index_options = klass.sphinx_index_options

I am trying to track down why the sphinx_internal_class attrib is not set, but any help would be appreciated.

hemang commented 12 years ago

I believe it has to do with differences in the way the class_crc and sphinx_internal_class query is generated in development.sphinx file:

sql_query = SELECT "users"."id" * 2::INT8 + 1 AS "id" , "users"."name" AS "name", "users"."id" AS "sphinx_internal_id", 0 AS "sphinx_deleted",

CASE COALESCE("users"."type", '') WHEN 'User' THEN 76111 WHEN 'OtherUser' THEN 15898 ELSE 76111 END AS "class_crc",

COALESCE("users"."type", '') AS "sphinx_internal_class",

0 AS "dest_id" FROM "users" WHERE ("users"."id" >= $start AND "users"."id" <= $end) GROUP BY "users"."id", "users"."name", "users"."id", "users"."type"

Notice how sphinx_internal_class doesn't set the 'User' class by default as sphinx_internal_class. If you provide the name of the base class as default for sphinx_internal_class, I believe it should fix the problem.

pat commented 12 years ago

I've just pushed a fix to sphinx_internal_class which should address this. If you could give it a spin soon, that'd be great - will be releasing new versions of the gems as soon as I can.

hemang commented 12 years ago

Great! Thanks for the update. I gave it a try and it works.

The fix generated a slightly verbose query with two coalesce statements, but that's fine with me.

COALESCE(CASE COALESCE("users"."type", 'User') WHEN 'User' THEN 'User' WHEN 'OtherUser' THEN 'OtherUser' ELSE 'User' END, '') AS "sphinx_internal_class"

instead of:

CASE COALESCE("users"."type", 'User') WHEN 'User' THEN 'User' WHEN 'OtherUser' THEN 'OtherUser' ELSE 'User' END

or,

CASE COALESCE("users"."type", '' ) WHEN 'User' THEN 'User' WHEN 'OtherUser' THEN 'OtherUser' ELSE 'User' END

Thanks again for taking care of this. Look forward to the new version release. In the meantime, should I point Gemfile on heroku to use :git => 'git://github.com/freelancing-god/thinking-sphinx.git' so flying sphinx will use the latest updates?

pat commented 12 years ago

Yup, just use the git reference for the moment. There's one or two things I want to clear up before the next gem release - hopefully this week.

And I know the statement is a bit verbose - ideally, the CASE statement isn't even needed, but that requires more reworking of code, may not be worthwhile right at this point.

On 12/05/2012, at 6:18 AM, hemang wrote:

Great! Thanks for the update. I gave it a try and it works.

The fix generated a slightly verbose query with two coalesce statements, but that's fine with me.

COALESCE(CASE COALESCE("users"."type", 'User') WHEN 'User' THEN 'User' WHEN 'NonUser' THEN 'NonUser' ELSE 'User' END, '') AS "sphinx_internal_class"

instead of:

CASE COALESCE("users"."type", 'User') WHEN 'User' THEN 'User' WHEN 'NonUser' THEN 'NonUser' ELSE 'User' END

or,

CASE COALESCE("users"."type", '' ) WHEN 'User' THEN 'User' WHEN 'NonUser' THEN 'NonUser' ELSE 'User' END

Thanks again for taking care of this. Look forward to the new version release. In the meantime, should I point Gemfile on heroku to use :git => 'git://github.com/freelancing-god/thinking-sphinx.git' so flying sphinx will use the latest updates?


Reply to this email directly or view it on GitHub: https://github.com/freelancing-god/thinking-sphinx/issues/348#issuecomment-5659971

micahwedemeyer commented 12 years ago

If you're having this problem, make sure to recreate the config and reindex (ie. rake ts:in) after upgrading to 2.0.12 Took me a while to figure that one out.

saturnflyer commented 12 years ago

I'm on a Rails 2 project and running into this problem. Can you point to the difference between the 1.x and 2.x versions so I can patch this locally?

pat commented 12 years ago

Hi Jim, the patch is in the 1.4.12 release as well (for Rails 2).

saturnflyer commented 12 years ago

Thanks, Pat. I'm still seeing the problem with 1.4.12.

NoMethodError (undefined method `sphinx_index_options' for Object:Class):
  /opt/Developer/.rbenv/versions/1.8.7-p352/lib/ruby/gems/1.8/gems/thinking-sphinx-1.4.12/lib/thinking_sphinx/search.rb:890:in `instances_from_class'
  /opt/Developer/.rbenv/versions/1.8.7-p352/lib/ruby/gems/1.8/gems/thinking-sphinx-1.4.12/lib/thinking_sphinx/search.rb:932:in `instances_from_matches'
  /opt/Developer/.rbenv/versions/1.8.7-p352/lib/ruby/gems/1.8/gems/thinking-sphinx-1.4.12/lib/thinking_sphinx/search.rb:930:in `instances_from_matches'
  /opt/Developer/.rbenv/versions/1.8.7-p352/lib/ruby/gems/1.8/gems/thinking-sphinx-1.4.12/lib/thinking_sphinx/search.rb:441:in `compose_results'
  /opt/Developer/.rbenv/versions/1.8.7-p352/lib/ruby/gems/1.8/gems/thinking-sphinx-1.4.12/lib/thinking_sphinx/search.rb:429:in `populate'
  /opt/Developer/.rbenv/versions/1.8.7-p352/lib/ruby/gems/1.8/gems/thinking-sphinx-1.4.12/lib/thinking_sphinx/search.rb:579:in `call'
  /opt/Developer/.rbenv/versions/1.8.7-p352/lib/ruby/gems/1.8/gems/thinking-sphinx-1.4.12/lib/thinking_sphinx/search.rb:579:in `retry_on_stale_index'
  /opt/Developer/.rbenv/versions/1.8.7-p352/lib/ruby/gems/1.8/gems/thinking-sphinx-1.4.12/lib/thinking_sphinx/search.rb:409:in `populate'
  /opt/Developer/.rbenv/versions/1.8.7-p352/lib/ruby/gems/1.8/gems/thinking-sphinx-1.4.12/lib/thinking_sphinx/search.rb:172:in `method_missing'
pat commented 12 years ago

Right, that's annoying. Can you confirm you've run rake ts:rebuild since updating Thinking Sphinx?

saturnflyer commented 12 years ago

Argh! Thank you for following up. I had forgotten to rebuild after going from 11 to 12. I'm back in business.

pat commented 12 years ago

No worries, and great to know that's what was needed - otherwise I would have been at a loss at what the problem could be! :)

Pat

On 25/06/2012, at 10:24 PM, Jim Gay wrote:

Argh! Thank you for following up. I had forgotten to rebuild after going from 11 to 12. I'm back in business.


Reply to this email directly or view it on GitHub: https://github.com/freelancing-god/thinking-sphinx/issues/348#issuecomment-6558583