2014-04-22 33 views
2

我有Ruby on Rails 4项目与Thinking Sphinx 3。我有几个型号:思维狮身人面像 - 与布尔字段嵌套关联

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 

我需要CheckOrders,其中有布尔字段approved找到Investmens。

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

所以,我想的是:

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

,但搜索找到什么:

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 
=> [] 

所以我决定尝试属性过滤器:

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

但它产生的错误:

$ 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). 

我该如何解决这个问题?

回答

2

Daiku是正确的,属性会满足您的需要更好的,但事实是,狮身人面像无法处理boolean类型的多值属性。

所以,需要一点解决方法 - 您需要确保包含check_orders的连接,然后您需要将SQL布尔转换为整数(true为1,false为0)。我认为以下应该做的伎俩(选择您使用的数据库的选项):

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 
+0

谢谢你的答案,帕特!但是,PostgreSQL的解决方案不起作用。我在我的'investment_index'文件中粘贴了你的代码,但是之后我在重建索引时遇到这样的错误:'indexing index'investment_core'... 错误:index'investment_core':sql_range_query:ERROR:语法错误处于或接近“THEN “ LINE 1:... ng(array_agg(DISTINCT(CASE check_orders.approved THEN 1 ELS ... (DSN = pgsql:// serj:*** @ localhost:5432/my-project_development)。如何修复... – ExiRe

+2

它看起来像我发现了问题!它应该是'CASE当...'。:) – ExiRe

+0

再次感谢您的解决方案!PostgreSQL的编辑后它完美!真棒! – ExiRe

0

属性过滤器绝对是一种布尔型字段。试着告诉狮身人面像的属性类型:

has investment_parts.check_orders.approved, as: :insuranced_investment_attr, type: :boolean 
相关问题