Вопрос

I have Ruby on Rails 4 project with Thinking Sphinx 3. I have few models:

class Investment < ActiveRecord::Base
  has_many :investment_parts 
end

class InvestmentPart < ActiveRecord::Base
  belongs_to :investment
  has_many :check_orders, dependent: :destroy
  has_many :legal_entity_insurance_companies, through: :check_orders, class_name: "LegalEntities::InsuranceCompany"
end

class CheckOrder < ActiveRecord::Base
  belongs_to :legal_entity_insurance_company, class_name: "LegalEntities::InsuranceCompany"
  belongs_to :investment_part
end

I need to find Investmens by CheckOrders, which have boolean fields approved.

  create_table "check_orders", force: true do |t|
    ...
    t.boolean  "approved", default: false
  end

So I tried that:

ThinkingSphinx::Index.define :investment, with: :active_record do
  indexes investment_parts.check_orders.approved, as: :insuranced_investment
end

But search find nothing:

2.0.0p353 :008 > CheckOrder.pluck(:approved)
   (0.6ms)  SELECT "check_orders"."approved" FROM "check_orders"
 => [true, true, true] 
2.0.0p353 :009 > Investment.search("", conditions: {insuranced_investment: true})
  Sphinx  Retrying query "SELECT * FROM `investment_core` WHERE MATCH('@insuranced_investment true') AND `sphinx_deleted` = 0 LIMIT 0, 20 OPTION max_matches=50000; SHOW META" after error: Lost connection to MySQL server during query
  Sphinx Query (3.5ms)  SELECT * FROM `investment_core` WHERE MATCH('@insuranced_investment true') AND `sphinx_deleted` = 0 LIMIT 0, 20 OPTION max_matches=50000
  Sphinx  Found 0 results
 => []

So i decided to try attribute filters:

ThinkingSphinx::Index.define :investment, with: :active_record do
  has investment_parts.check_orders.approved, as: :insuranced_investment_attr
end

But it generates error:

$ rake ts:rebuild
Stopped searchd daemon (pid: 15516).
Generating configuration to /Projects/my-project/config/development.sphinx.conf
Sphinx 2.1.4-release (rel21-r4421)
...
using config file '/Projects/my-project/config/development.sphinx.conf'...
...
indexing index 'investment_core'...
ERROR: source 'investment_core_0': expected attr type ('uint' or 'timestamp' or 'bigint') in sql_attr_multi, got 'bool insuranced_investment_attr from field'.
ERROR: index 'investment_core': failed to configure some of the sources, will not index.
...
total 15 reads, 0.000 sec, 0.7 kb/call avg, 0.0 msec/call avg
total 50 writes, 0.000 sec, 0.5 kb/call avg, 0.0 msec/call avg
Started searchd successfully (pid: 15556).

How can i fix that?

Это было полезно?

Решение

Daiku is right that attributes are going to suit your need better, but the fact is that Sphinx can't handle multi-value attributes of type boolean.

So, a bit of a work around is going to be needed - you'll want to ensure the join down to check_orders is included, and then you'll want to have a SQL snippet converting booleans to integers (true is 1, false is 0). I think the following should do the trick (choose the option for the database you're using):

join investment_parts.check_orders

# for PostgreSQL:
has "array_to_string(array_agg(DISTINCT (CASE check_orders.approved THEN 1 ELSE 0 END)), ',')",
  as: :insuranced_investment_attr, type: :integer, multi: true
# for MySQL:
has "GROUP_CONCAT(DISTINCT (CASE check_orders.approved THEN 1 ELSE 0 END) SEPARATOR ',')",
  as: :insuranced_investment_attr, type: :integer, multi: true

Другие советы

Attribute filters is definitely the way to go for a boolean field. Try telling sphinx the attribute type:

has investment_parts.check_orders.approved, as: :insuranced_investment_attr, type: :boolean
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top