ruby on rails - Using crc32 tweak on has_many relations in Thinking Sphinx -
it's weird actually. have 2 models have has_many relation each other, here models
#model city class city < activerecord::base belong_to :state end #model state class state < activerecord::base has_many :city end
and have state index
thinkingsphinx::index.define 'state', :with => :active_record indexes state_name, :sortable => true #here problem has "crc32(cities.city_name)", :as => :city_name, :type => :integer end
i want use city_name filter. code above doesn't work , got error message when run
rake ts:index
here error message
error: index 'state_core': sql_range_query: unknown column 'cities.city_name' in 'field list'
but, when put city_name in indexes block below, indexer runs well!
thinkingsphinx::index.define 'state', :with => :active_record indexes state_name, :sortable => true indexes cities.city_name has "crc32(cities.city_name)", :as => :city_name, :type => :integer end
any suggestions ?
thinking sphinx can't tell if you're referring association tables within sql snippets - in first example, there's nothing indicating needs join on cities.
the join
method within index definition exists purpose - so, try following:
thinkingsphinx::index.define 'state', :with => :active_record indexes state_name, :sortable => true has "crc32(cities.city_name)", :as => :city_name, :type => :integer join cities end
however, it's worth noting few things: firstly, may need add cities.city_name
group by
clause, since it's not part of aggregate values:
# within index definition group_by 'cities.city_name
but also: state model has many cities, not one, should aggregated set of integer values, not one. means don't need group_by
call, need add aggregate behaviour yourself. done differently depending on whether you're using postgresql or mysql:
# postgresql has "array_to_string(array_agg(crc32(cities.name)), ',')", :as => :city_names, :type => :integer, :multi => true # mysql has "group_concat(crc32(cities.name) separator ',')", :as => :city_names, :type => :integer, :multi => true
crc32
not native function in postgresql, , may need add yourself. thinking sphinx prior v3 did you, i've rewritten crc32 function no longer required. largely due fact crc32 can result in collisions, , can't reversed, , it's inelegant , imperfect solution. hence, think using fields string comparison better, it's whether preferred in app.
i recommend approach instead:
thinkingsphinx::index.define :state, :with => :active_record indexes state_name, :sortable => true has cities.id, :as => :city_ids end city = city.find_by_name('melbourne') state.search :with => {:city_ids => city.id}
it's accurate , elegant.
Comments
Post a Comment