2017-05-30 108 views
0

我想在我的Rails 5项目中使用ThinkingSphinx。我在http://freelancing-gods.com/thinking-sphinx/ThinkingSphinx:SQL支持索引上的OR条件?

上读取指令我需要在SQL支持索引上实现OR逻辑。

这里是我的类:

class Message < ApplicationRecord 
    belongs_to :sender, class_name: 'User', :inverse_of => :messages 
    belongs_to :recipient, class_name: 'User', :inverse_of => :messages 
end 

及其索引:

ThinkingSphinx::Index.define :message, :with => :active_record, :delta => true do 
    indexes text 

    indexes sender.email, :as => :sender_email, :sortable => true 

    indexes recipient.email, :as => :recipient_email, :sortable => true 

    has sender_id, created_at, updated_at 

    has recipient_id 

end 

schema.rb:

create_table "messages", force: :cascade do |t| 
    t.integer "sender_id" 
    t.integer "recipient_id" 
    t.text  "text" 
    t.datetime "created_at",     null: false 
    t.datetime "updated_at",     null: false 
    t.boolean "read",   default: false 
    t.boolean "spam",   default: false 
    t.boolean "delta",  default: true, null: false 
    t.index ["recipient_id"], name: "index_messages_on_recipient_id", using: :btree 
    t.index ["sender_id"], name: "index_messages_on_sender_id", using: :btree 
    end 

所以我需要在搜索仅在2个指标一次 - :sender_email:recipient_email - 但ignorin g indexes text

伪代码,我需要这样的:

Message.search '[email protected]' :conditions => {:sender_email => '[email protected]' OR :receiver_email => '[email protected]'} 

这意味着:找到所有“[email protected]”和“[email protected]”的消息(他们每个人可以是一个发件人或收件人) - 忽略包含文字的消息,文字为'[email protected]'或'[email protected]'。

不幸的是,该文件说:

The :conditions option must be a hash, with each key a field and each value a string. 

换句话说,我需要一个条件指标集(在运行时) - 但同时在2个索引(而不是1,记录)。

我的意思是只允许散列作为条件是一个坏主意 - 并且没有字符串(如ActiveRecord查询确实允许http://guides.rubyonrails.org/active_record_querying.html#pure-string-conditions)。

PS我会说ThinkingSphinx文档http://freelancing-gods.com/thinking-sphinx/是非常糟糕的,需要从头开始完全重写。我读了这一切,什么都不明白。它没有例子(完整的例子 - 只有部分 - 因此完全不清楚)。我甚至不明白什么是领域和属性,它们又有什么不同。协会,条件等 - 都不清楚。很坏。宝石本身看起来不错 - 但它的文档很糟糕。

回答

0

很遗憾听到您在文档中找不到适合您的解决方案。 Sphinx的挑战在于它使用SphinxQL语法,它与SQL非常相似,但有时也有很大不同 - 所以人们经常期望类似于SQL的行为。

这也是保持这种gem挑战的一部分 - 我不确定模拟ActiveRecord语法是否太明智,否则会使事情更加混乱。

这里要注意的关键问题是,你可以利用的狮身人面像的extended query syntax的比赛,以获取您的行为后:

Message.search :conditions => { 
    :sender_email => "([email protected] | [email protected])", 
    :receiver_email => "([email protected] | [email protected])" 
} 

这将返回任何地方发送者或者是两个值,接收器是两个值之一。当然,这包括从客户端1发送到客户端1,或manager1以manager1的任何消息,但是我希望这是罕见的,也许不是什么大不了的问题。

需要注意的一点是,@.通常不被视为可搜索单词字符,因此您可能需要add them to your charset_table

此外,由于你实际上执行确切的数据库列的整个值匹配,这并不觉得这实际上是由一些数据库索引的列更好的服务,并使用SQL而不是查询。狮身人面像(我会说大多数/所有其他全文搜索库)最适合在较大文本字段内匹配单词和短语。

至于文档...我已经投入了大量的精力试图让他们有用的,虽然我知道还是有很多改进,可以采取地方。我确实有一个页面,概述了how fields and attributes differ - 如果不明确,反馈肯定是受欢迎的。

饲养文件跟上时代的需要小型和新项目了很多的努力 - 与思考狮身人面像既不是这些,是在几个月的10岁左右。我为它仍然运行得很好而感到骄傲,它仍然支持最新版本的Rails,并且仍然得到积极维护和支持。但它是开源的 - 它是在我(和其他人)的业余时间完成的。这并不完美。如果你找到改进的方法,那么请做贡献!代码和文档位于GitHub上,并且非常欢迎pull请求。