2017-05-30 109 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請求。