我是Ruby和ThinkingSphinx的新手。我有以下Sphinx查询- SELECT * FROM user_core,user_delta WHERE sphinx_deleted = 0。
我不希望看到条件"WHERE ' sphinx_deleted‘= 0.我如何删除它?“我已经从我的sphinx.conf文件中删除了sql_attr_uint = sphinx_deleted,但我看到查询中传递了sphinx_deleted。
下面是索引文件的定义:
ThinkingSphinx::Index.define :user, :with => :active_record, :delta => true do
indexes [first_name,last_name,display_name], :as=>:name, :sortable=>true
indexes first_name, :sortable => true
indexes last_name, :sortable => true
indexes display_name, :sortable => true
indexes email, :sortable => true
indexes phone, :sortable => true
indexes title, :sortable => true
has id, :as => :user_id
has roles(:id), :as => :role_ids
has jurisdictions(:id), :as => :jurisdiction_ids
set_property :delta => true
end我没有定义sphinx_scope或default_sphinx_scope。
我们使用的是sphinx sphinx-3.1.0和ruby-2.1.0
发布于 2016-03-04 11:58:07
sphinx_deleted属性是由Sphinx创建的,用于以下情况(使用示例中具有核心和增量索引的用户模型的场景):
sphinx_deleted设置为1-如果底层ActiveRecord对象不再存在,则返回Sphinx记录没有意义。这就是该属性存在的原因。你不能告诉Thinking不要添加它,也不能删除那个过滤器,除非在Thinking的内部胡乱摆弄。
如果有想要删除属性和过滤器的特定原因,请随时在此处发表评论,或者您可以在the GitHub repo上打开问题,或发布到TS Google Group。
更新
好的,接下来,有三种方法可以绕过它。
选项一:
第一种方法是自己向Sphinx发出查询,使用Thinking连接:
results = ThinkingSphinx::Connection.take do |connection|
connection.execute "SELECT * FROM user_core, user_delta"
end请记住,这将返回原始的Sphinx值,而不是ActiveRecord实例。
选项二:
不过,一种更复杂的替代方案是拥有自己的搜索中间件堆栈。首先,您需要创建一个删除:sphinx_deleted过滤器的ThinkingSphinx::Middlewares::SphinxQL的自定义子类:
class SphinxQLWithoutFilter < ThinkingSphinx::Middlewares::SphinxQL
def call(contexts)
contexts.each do |context|
Inner.new(context).call
end
app.call contexts
end
private
class Inner < ThinkingSphinx::Middlewares::SphinxQL::Inner
def inclusive_filters
super.except :sphinx_deleted
end
end
end然后,创建一个使用这个新的SphinxQL查询中间件的新中间件堆栈:
WithoutFilterMiddleware = ::Middleware::Builder.new do
use ThinkingSphinx::Middlewares::StaleIdFilter
use SphinxQLWithoutFilter
use ThinkingSphinx::Middlewares::Geographer
use ThinkingSphinx::Middlewares::Inquirer
use ThinkingSphinx::Middlewares::ActiveRecordTranslator
use ThinkingSphinx::Middlewares::StaleIdChecker
use ThinkingSphinx::Middlewares::Glazier
end然后,您可以在特定的搜索查询中使用该中间件堆栈:
User.search 'foo', :middleware => WithoutFilterMiddleware值得注意的是,该堆栈中存在两个用于陈旧ids的中间件。它们协同工作以捕获没有匹配ActiveRecord对象的任何Sphinx结果,并重新运行Sphinx查询最多三次,以过滤掉那些不匹配的记录。它们可能很有用,但如果您不想使用它们,可以从自定义堆栈中删除它们。但是,如果没有它们,任何没有匹配ActiveRecord对象的Sphinx记录都将被转换为nils。
选项三:
这是前一个解决方案的更多黑客版本,但将适用于所有搜索,因此可能不值得:使用class_eval重新打开添加过滤器的类,并更改方法定义:
ThinkingSphinx::Middlewares::SphinxQL::Inner.class_eval do
def inclusive_filters
# normally:
# (options[:with] || {}).merge({:sphinx_deleted => false})
# but without the sphinx_deleted filter:
options[:with] || {}
end
end现在,所有这些都表明:我假设你实际上并没有删除用户,但不知何故删除回调还是被触发了?因此,用户确实存在,但目前正在被Sphinx过滤掉?如果是这样的话,我强烈建议不要使用ActiveRecord的destroy方法,而是使用一个自定义方法将用户标记为非活动。这避免了回调,从而避免了对上述任何“解决方案”的需要。
https://stackoverflow.com/questions/35782462
复制相似问题