thinking-sphinx index minimum

时光怂恿深爱的人放手 提交于 2020-01-26 03:20:09

问题


I have a Product & Price models, where:

class Product < AR::Base
  has_many :prices # there are several types of prices, e.g. for guests, users et.c.

I want to index and sort products by price values, belonging to this product and exact price_type.

ThinkingSphinx::Index.define :product, with: :active_record do
  indexes name
  indexes k1c
  indexes catalogue_code
  indexes created_at, sortable: true
  indexes prices(:value), as: :price, sortable: true # TODO

  has :category_id
  has :brand_id
  has :kind_cd
  has :price_id
end

After rake ts:rebuild I get that

rake aborted!
NoMethodError: undefined method `type' for nil:NilClass
/home/asiniy/.rvm/gems/ruby-2.1.0@zhivojoffice/gems/thinking-sphinx-3.1.0/lib/thinking_sphinx/active_record/attribute/type.rb:64:in `type_from_database'
/home/asiniy/.rvm/gems/ruby-2.1.0@zhivojoffice/gems/thinking-sphinx-3.1.0/lib/thinking_sphinx/active_record/attribute/type.rb:17:in `type'
/home/asiniy/.rvm/gems/ruby-2.1.0@zhivojoffice/gems/thinking-sphinx-3.1.0/lib/thinking_sphinx/active_record/attribute.rb:4:in `type'
/home/asiniy/.rvm/gems/ruby-2.1.0@zhivojoffice/gems/thinking-sphinx-3.1.0/lib/thinking_sphinx/active_record/attribute/sphinx_presenter.rb:30:in `sphinx_type'
/home/asiniy/.rvm/gems/ruby-2.1.0@zhivojoffice/gems/thinking-sphinx-3.1.0/lib/thinking_sphinx/active_record/attribute/sphinx_presenter.rb:18:in `collection_type'
/home/asiniy/.rvm/gems/ruby-2.1.0@zhivojoffice/gems/thinking-sphinx-3.1.0/lib/thinking_sphinx/active_record/sql_source.rb:96:in `block in append_presenter_to_attribute_array'
/home/asiniy/.rvm/gems/ruby-2.1.0@zhivojoffice/gems/thinking-sphinx-3.1.0/lib/thinking_sphinx/active_record/sql_source.rb:93:in `each'
/home/asiniy/.rvm/gems/ruby-2.1.0@zhivojoffice/gems/thinking-sphinx-3.1.0/lib/thinking_sphinx/active_record/sql_source.rb:93:in `append_presenter_to_attribute_array'
/home/asiniy/.rvm/gems/ruby-2.1.0@zhivojoffice/gems/thinking-sphinx-3.1.0/lib/thinking_sphinx/active_record/sql_source.rb:132:in `prepare_for_render'
/home/asiniy/.rvm/gems/ruby-2.1.0@zhivojoffice/gems/thinking-sphinx-3.1.0/lib/thinking_sphinx/active_record/sql_source.rb:65:in `render'
/home/asiniy/.rvm/gems/ruby-2.1.0@zhivojoffice/gems/riddle-1.5.10/lib/riddle/configuration/index.rb:29:in `block in render'
/home/asiniy/.rvm/gems/ruby-2.1.0@zhivojoffice/gems/riddle-1.5.10/lib/riddle/configuration/index.rb:29:in `collect'
/home/asiniy/.rvm/gems/ruby-2.1.0@zhivojoffice/gems/riddle-1.5.10/lib/riddle/configuration/index.rb:29:in `render'
/home/asiniy/.rvm/gems/ruby-2.1.0@zhivojoffice/gems/thinking-sphinx-3.1.0/lib/thinking_sphinx/core/index.rb:53:in `render'
/home/asiniy/.rvm/gems/ruby-2.1.0@zhivojoffice/gems/riddle-1.5.10/lib/riddle/configuration.rb:41:in `block in render'
/home/asiniy/.rvm/gems/ruby-2.1.0@zhivojoffice/gems/riddle-1.5.10/lib/riddle/configuration.rb:41:in `collect'
/home/asiniy/.rvm/gems/ruby-2.1.0@zhivojoffice/gems/riddle-1.5.10/lib/riddle/configuration.rb:41:in `render'
/home/asiniy/.rvm/gems/ruby-2.1.0@zhivojoffice/gems/thinking-sphinx-3.1.0/lib/thinking_sphinx/configuration.rb:88:in `render'
/home/asiniy/.rvm/gems/ruby-2.1.0@zhivojoffice/gems/thinking-sphinx-3.1.0/lib/thinking_sphinx/configuration.rb:94:in `block in render_to_file'
/home/asiniy/.rvm/gems/ruby-2.1.0@zhivojoffice/gems/thinking-sphinx-3.1.0/lib/thinking_sphinx/configuration.rb:94:in `render_to_file'
/home/asiniy/.rvm/gems/ruby-2.1.0@zhivojoffice/gems/thinking-sphinx-3.1.0/lib/thinking_sphinx/rake_interface.rb:13:in `configure'
/home/asiniy/.rvm/gems/ruby-2.1.0@zhivojoffice/gems/thinking-sphinx-3.1.0/lib/thinking_sphinx/rake_interface.rb:24:in `index'
/home/asiniy/.rvm/gems/ruby-2.1.0@zhivojoffice/gems/thinking-sphinx-3.1.0/lib/thinking_sphinx/tasks.rb:9:in `block (2 levels) in <top (required)>'
/home/asiniy/.rvm/gems/ruby-2.1.0@zhivojoffice/bin/ruby_executable_hooks:15:in `eval'
/home/asiniy/.rvm/gems/ruby-2.1.0@zhivojoffice/bin/ruby_executable_hooks:15:in `<main>'
Tasks: TOP => ts:rebuild => ts:index

Need I write a raw SQL query or there is another method?

UPD

Analogue sql query for get a one price (after that I want to order by price):

SELECT "prices".* FROM "prices" WHERE "prices"."product_id" = $1 AND "prices"."price_type_id" = 1 LIMIT 1

My prices model. Quantity of price_types are about 5 and changes very seldom.

class Price < ActiveRecord::Base
  validates :price_type, :value, :product, presence: true
  validates :price_type, uniqueness: { scope: :product }
  validates :value, numericality: { greater_than: 0.0 }

  belongs_to :price_type
  belongs_to :product
end

回答1:


There's a couple of things to note here.

Firstly: attributes are a better fit for sorting (they're sortable by their very nature)... but yes, if you want to sort by the minimum price, then you're going to need a SQL snippet for that:

has 'MIN(prices.value)', as: :price, type: :float

You will also need to ensure you're referring to the prices association either in a separate field or attribute, or explicitly in a call to join, to ensure the table is actually part of the joins in the generated SQL query:

join prices

However, the error you're seeing is unrelated to this - it's complaining that it can't determine the type of an attribute because the specified column doesn't exist. I'm pretty certain this is from your price_id attribute, which should probably go through the prices association:

has prices.id, as: :price_ids

Making this change has the added bonus of ensuring the SQL join exists for the prices table, and so you don't need the join prices line in your index definition.



来源:https://stackoverflow.com/questions/23152124/thinking-sphinx-index-minimum

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!