思考 - 斯芬克斯指数最小化

时间:2014-04-18 10:22:57

标签: ruby-on-rails ruby sphinx thinking-sphinx

我有一个产品&价格模型,其中:

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

我想按价格值对产品进行索引和排序,属于此产品和确切的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

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

我需要编写原始SQL查询还是有其他方法?

UPD

模拟sql查询获得一个价格(之后我想按价格订购):

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

我的价格模型。 price_types的数量大约为5,很少变化。

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 个答案:

答案 0 :(得分:1)

这里有几点需要注意。

首先:属性更适合排序(它们的性质可以排序)......但是,如果你想按最低价格排序,那么你将需要一个SQL代码片段:

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

您还需要确保在单独的字段或属性中引用prices关联,或明确地在join的调用中引用join prices 关联,以确保该表实际上是加入生成的SQL查询:

price_id

但是,您看到的错误与此无关 - 它抱怨它无法确定属性的类型,因为指定的列不存在。我很确定这是来自您的prices属性,该属性应该通过has prices.id, as: :price_ids 关联:

prices

进行此更改还有确保join prices表存在SQL连接的额外好处,因此您不需要索引定义中的{{1}}行。