在我的Rails應用程序中,我有一個「術語」模型,它存儲術語(關鍵字)以及它在特定文檔集中出現的頻率一個整數)。無論何時將新文檔添加到集合中,我都會解析出單詞,然後我需要將新術語及其頻率插入術語表中,或者我需要更新現有術語的頻率。Rails - 插入新數據,或增加更新的現有值
最簡單的方法是做一個查找,然後如果它是空的做一個插入,或者如果它不是空的,按正確的數量增加現有記錄的頻率。然而,每個單詞有兩個查詢,並且具有高字數的文檔將導致查詢的長度很長。有沒有更有效的方法來做到這一點?
在我的Rails應用程序中,我有一個「術語」模型,它存儲術語(關鍵字)以及它在特定文檔集中出現的頻率一個整數)。無論何時將新文檔添加到集合中,我都會解析出單詞,然後我需要將新術語及其頻率插入術語表中,或者我需要更新現有術語的頻率。Rails - 插入新數據,或增加更新的現有值
最簡單的方法是做一個查找,然後如果它是空的做一個插入,或者如果它不是空的,按正確的數量增加現有記錄的頻率。然而,每個單詞有兩個查詢,並且具有高字數的文檔將導致查詢的長度很長。有沒有更有效的方法來做到這一點?
實際上,您可以非常有效地做到這一點。那麼,如果你不害怕調整Rails的默認表格佈局一點,如果你不害怕生成自己的原始SQL ...
我會假設你正在使用MySQL數據庫(我不確定其他數據庫支持這個):你可以使用INSERT ... ON DUPLICATE KEY UPDATE來做到這一點。
你必須調整你的計數表才能使它工作,但「重複鍵」只是指主鍵,而Rails的默認ID,它只是一個任意數字,不會幫助你。您需要更改主鍵,以便確定每條記錄的獨特性 - 在您的情況下,我會說PRIMARY KEY(word, document_set_id)
。默認情況下,Rails可能不支持這種方式,但至少有一個plugin,如果您不喜歡那個,可能還會多一個。
一旦你的數據庫設置好了,你可以構建一個巨大的插入語句,然後在MySQL中拋出它,讓查詢的「重複鍵」部分照顧到惡意的存在 - 檢查你的東西(注意:有插件做批量插入,太多,但我不;知道他們是如何工作 - 特別是在「關於重複鍵」問候):
counts = {}
#This is just demo code! Untested, and it'll leave in punctuation...
@document.text.split(' ').each do |word|
counts[word] ||= 0
counts[word] += 1
end
values = []
counts.each_pair do |word, count|
values << ActiveRecord::Base.send(:sanitize_sql_array, [
'(?, ?, ?)',
word,
@document.set_id,
count
])
end
#Massive line - sorry...
ActiveRecord::Base.connection.execute("INSERT INTO word_counts (word, document_set_id, occurences) VALUES ${values.join(', ')} ON DUPLICATE KEY UPDATE occurences = occurences + VALUES(occurences)")
這會做到這一點 - 在一個SQL查詢整個新文件。應該快得多,一半是因爲你只運行一個查詢,另一半是因爲你已經避開了ActiveRecord的緩慢查詢構建。
希望有幫助!
您正在回答你自己的問題。無論你做什麼,你總是需要一個查找和創建/更新每個單詞。 – nunopolonia 2011-02-07 01:30:13