繁体   English   中英

Rails-插入新数据,或通过更新来增加现有值

[英]Rails - insert new data, or increment existing value with update

在我的Rails应用程序中,我有一个“术语”模型,该模型存储术语(关键字)及其在特定文档集中出现的频率(整数)。 每当将新文档添加到集合中时,我都会解析单词,然后需要在术语表中插入新术语及其频率,或者需要更新现有术语的频率。

最简单的方法是进行查找,然后,如果为空则执行插入操作,或者如果不为空,则将现有记录的频率增加正确的数量。 这是每个单词两个查询,但是单词数量多的文档将导致冗长的查询列表。 有没有更有效的方法可以做到这一点?

实际上,您可以真正有效地做到这一点。 好吧,如果您不害怕稍微调整Rails的默认表布局,并且不害怕生成自己的原始SQL ...

我将假设您正在为数据库使用MySQL(我不确定其他数据库是否支持此功能):您可以使用INSERT ... ON DUPLICATE KEY UPDATE来执行此操作。

但是,您必须调整计数表才能使它起作用,-“重复键上”仅是指主键,而Rails的默认ID(只是一个任意数字)将无济于事。 您需要更改您的主键,以便识别导致每个记录唯一的原因-在您的情况下,我会说PRIMARY KEY(word, document_set_id) 默认情况下,Rails可能不支持此功能,但是至少有一个插件 ,如果您不喜欢的话,可能还有更多插件

建立数据库后,您可以构建一个巨型插入语句,并将其引发到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缓慢的查询构建过程。

希望有帮助!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM