これは本当に効率的に行うことができます。もしあなたがRailsのデフォルトのテーブルレイアウトを微調整するのを恐れていないなら、あなた自身の生のSQLを生成することを恐れていなければ...
私はあなたのためにMySQLを使用していると仮定しますデータベース(他のDBがこれをサポートしているかどうか不明):INSERT ... ON DUPLICATE KEY UPDATEを使ってこれを行うことができます。
"重複キーで"はプライマリキーのみを参照し、RailsのデフォルトIDは任意の数値であり、あなたの手助けにはなりませんが、カウントテーブルを調整する必要があります。あなたのプライマリキーを変更して、各レコードをユニークにするものを識別できるようにする必要があります。あなたのケースでは、私はPRIMARY KEY(word, document_set_id)
と言います。これはデフォルトではRailsではサポートされていないかもしれませんが、少なくとも1つのpluginがあります。
データベースが設定されたら、1つの巨大なinsert文を作成してMySQLに投げて、クエリの "重複したキー"部分があなたのために厄介な存在チェックをするようにすることができます(注:そこにも、バッチ挿入を行うためのプラグインがありますが、私はドン; tは、彼らがどのように動作するかを知っている - )、特に「重複キーオン」に関してで:
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)")
そして、それはそれを行うだろう - のための1つのSQLクエリ新しい文書全体。はるかに速く、半分はあなたが1つのクエリだけを実行しているため、半分はActiveRecordの遅いクエリ構築を回避したためです。
希望に役立ちます!
あなた自身の質問に答えています。あなたが何をしても、単語ごとに検索と作成/更新が常に必要になります。 – nunopolonia