思考sphinx - 允许null和OR Logic与属性过滤器

时间:2014-07-10 11:45:08

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

我有这样的索引:

ThinkingSphinx::Index.define :service, with: :active_record do
  # ...
  has currency, as: :currency_attr
end

我需要能够按货币搜索并允许空值。所以我尝试这个解决方案(通过official docs):

with_null_currency = "*, IF(currency = 1 OR currency IS NULL) AS my_currency"
Service.search('', :select => with_null_currency, :with  => {'my_currency' => 1})

但它不会以某种方式起作用:

  Sphinx Query (7.1ms)  SELECT *, IF(currency = 1 OR currency IS NULL) AS my_currency FROM `service_core` WHERE `my_currency` = 1 AND `sphinx_deleted` = 0 LIMIT 0, 20 OPTION max_matches=500000
ThinkingSphinx::SyntaxError: sphinxql: syntax error, unexpected IDENT, expecting ')' or ',' near 'IS NULL) AS my_currency FROM `service_core` WHERE `my_currency` = 1 AND `sphinx_deleted` = 0 LIMIT 0, 20 OPTION max_matches=500000; SHOW META' - SELECT *, IF(currency = 1 OR currency IS NULL) AS my_currency FROM `service_core` WHERE `my_currency` = 1 AND `sphinx_deleted` = 0 LIMIT 0, 20 OPTION max_matches=500000; SHOW META
    from /Users/serj/.rvm/gems/ruby-2.0.0-p353@gearup/gems/thinking-sphinx-3.1.1/lib/thinking_sphinx/connection.rb:91:in `rescue in query'
    from /Users/serj/.rvm/gems/ruby-2.0.0-p353@gearup/gems/thinking-sphinx-3.1.1/lib/thinking_sphinx/connection.rb:94:in `query'
    from /Users/serj/.rvm/gems/ruby-2.0.0-p353@gearup/gems/thinking-sphinx-3.1.1/lib/thinking_sphinx/connection.rb:75:in `query_all'
    from /Users/serj/.rvm/gems/ruby-2.0.0-p353@gearup/gems/thinking-sphinx-3.1.1/lib/thinking_sphinx/search/batch_inquirer.rb:17:in `block in results'
    from /Users/serj/.rvm/gems/ruby-2.0.0-p353@gearup/gems/thinking-sphinx-3.1.1/lib/thinking_sphinx/connection.rb:37:in `block in take'
    from /Users/serj/.rvm/gems/ruby-2.0.0-p353@gearup/gems/innertube-1.1.0/lib/innertube.rb:138:in `take'
    from /Users/serj/.rvm/gems/ruby-2.0.0-p353@gearup/gems/thinking-sphinx-3.1.1/lib/thinking_sphinx/connection.rb:35:in `take'
    from /Users/serj/.rvm/gems/ruby-2.0.0-p353@gearup/gems/thinking-sphinx-3.1.1/lib/thinking_sphinx/search/batch_inquirer.rb:16:in `results'
    from /Users/serj/.rvm/gems/ruby-2.0.0-p353@gearup/gems/thinking-sphinx-3.1.1/lib/thinking_sphinx/middlewares/inquirer.rb:9:in `block in call'
    from /Users/serj/.rvm/gems/ruby-2.0.0-p353@gearup/gems/activesupport-4.1.1/lib/active_support/notifications.rb:159:in `block in instrument'
    from /Users/serj/.rvm/gems/ruby-2.0.0-p353@gearup/gems/activesupport-4.1.1/lib/active_support/notifications/instrumenter.rb:20:in `instrument'
    from /Users/serj/.rvm/gems/ruby-2.0.0-p353@gearup/gems/activesupport-4.1.1/lib/active_support/notifications.rb:159:in `instrument'
    from /Users/serj/.rvm/gems/ruby-2.0.0-p353@gearup/gems/thinking-sphinx-3.1.1/lib/thinking_sphinx/logger.rb:3:in `log'
    from /Users/serj/.rvm/gems/ruby-2.0.0-p353@gearup/gems/thinking-sphinx-3.1.1/lib/thinking_sphinx/middlewares/inquirer.rb:8:in `call'
    from /Users/serj/.rvm/gems/ruby-2.0.0-p353@gearup/gems/thinking-sphinx-3.1.1/lib/thinking_sphinx/middlewares/geographer.rb:11:in `call'
    from /Users/serj/.rvm/gems/ruby-2.0.0-p353@gearup/gems/thinking-sphinx-3.1.1/lib/thinking_sphinx/middlewares/sphinxql.rb:14:in `call'
... 6 levels...
    from /Users/serj/.rvm/gems/ruby-2.0.0-p353@gearup/gems/railties-4.1.1/lib/rails/commands/console.rb:9:in `start'
    from /Users/serj/.rvm/gems/ruby-2.0.0-p353@gearup/gems/railties-4.1.1/lib/rails/commands/commands_tasks.rb:69:in `console'
    from /Users/serj/.rvm/gems/ruby-2.0.0-p353@gearup/gems/railties-4.1.1/lib/rails/commands/commands_tasks.rb:40:in `run_command!'
    from /Users/serj/.rvm/gems/ruby-2.0.0-p353@gearup/gems/railties-4.1.1/lib/rails/commands.rb:17:in `<top (required)>'
    from /Users/serj/.rvm/gems/ruby-2.0.0-p353@gearup/gems/activesupport-4.1.1/lib/active_support/dependencies.rb:247:in `require'
    from /Users/serj/.rvm/gems/ruby-2.0.0-p353@gearup/gems/activesupport-4.1.1/lib/active_support/dependencies.rb:247:in `block in require'
    from /Users/serj/.rvm/gems/ruby-2.0.0-p353@gearup/gems/activesupport-4.1.1/lib/active_support/dependencies.rb:232:in `load_dependency'
    from /Users/serj/.rvm/gems/ruby-2.0.0-p353@gearup/gems/activesupport-4.1.1/lib/active_support/dependencies.rb:247:in `require'
    from /Users/serj/Projects/gearup/bin/rails:8:in `<top (required)>'
    from /Users/serj/.rvm/gems/ruby-2.0.0-p353@gearup/gems/activesupport-4.1.1/lib/active_support/dependencies.rb:241:in `load'
    from /Users/serj/.rvm/gems/ruby-2.0.0-p353@gearup/gems/activesupport-4.1.1/lib/active_support/dependencies.rb:241:in `block in load'
    from /Users/serj/.rvm/gems/ruby-2.0.0-p353@gearup/gems/activesupport-4.1.1/lib/active_support/dependencies.rb:232:in `load_dependency'
    from /Users/serj/.rvm/gems/ruby-2.0.0-p353@gearup/gems/activesupport-4.1.1/lib/active_support/dependencies.rb:241:in `load'
    from /Users/serj/.rvm/rubies/ruby-2.0.0-p353/lib/ruby/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:55:in `require'
    from /Users/serj/.rvm/rubies/ruby-2.0.0-p353/lib/ruby/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:55:in `require'

我怎样才能让它发挥作用?

P.S。我使用gem thinking-sphinx 3.1.1Sphinx 2.1.4-release (rel21-r4421),PostgreSQL和Rails 4.1

3 个答案:

答案 0 :(得分:1)

你在SQ​​L查询中编写错误的IF如下所示:

with_null_currency = "*, IF(currency = 1 OR currency IS NULL, 1, 0) AS my_currency"

OR

with_null_currency = "*, IF(currency = 1 OR currency IS NULL, true, false) AS my_currency"

答案 1 :(得分:1)

请记住,您所编写的内容不是SQL,而是SphinxQL - 类似但不完全相同。此外,NULL不作为Sphinx的概念存在 - 它在索引到空字符串(对于字段)或0(对于整数,时间戳,浮点数,布尔值)时转换NULL。

另外,Ahmad关于IF is correct的三个参数的建议,这意味着SELECT子句最终看起来像这样:

with_null_currency = "*, IF(currency = 1 OR currency = 0, 1, 0) as my_currency"

现在,这可能不是您实际执行的操作的正确行为,但可能需要调整Sphinx索引结构。

答案 2 :(得分:0)

我要感谢帕特的帮助。问题是我在索引定义中使用了别名。这就是出现这种错误的原因。所以,要解决这个问题,我需要使用这行代码:

with_null_currency = "*, IF(currency_attr = 1 OR currency_attr = 0, 1, 0) as my_currency"
Service.search('', select: with_null_currency, with: {my_currency: 1})

Pat更新了文档以提及此问题。

相关问题