Ruby 部分检索大量记录并迭代它们

Iva*_*hko 1 ruby collections iterator ruby-on-rails persistent-storage

我是 Ruby 的新手,但我在其他编程语言方面有很多经验。我需要迭代大量记录(来自数据库或任何持久存储)。存储引擎允许我按范围部分检索记录。在 PHP 中,我通常编写自定义迭代器来加载一系列记录并对其进行迭代,并在需要时加载记录的下一部分并忘记上一部分。脚本内存使用和存储请求计数之间的一些权衡。像这样的东西(从这里的评论复制):

class Database_Result_Iterator {
...
private $_db_resource = null;
private $_loaded = false;
private $_valid = false;

function rewind() {
    if ($this->_db_resource) {
        mysql_free($this->_db_resource);
        $this->_db_resource = null;
    }
    $this->_loaded = false;
    $this->_valid = false;
}

function valid() {
    if ($this->_loaded) {
        $this->load();
    }
    return $this->_valid;
}

private function load() {
    $this->_db_resource = mysql_query(...);
    $this->_loaded = true;
    $this->next(); // Sets _valid
}
Run Code Online (Sandbox Code Playgroud)

}

这种方法在 Ruby 中是如何转变的?即我有一些Voter类和get_votes方法,它返回属于当前投票者对象的所有选票。可以检索的不是包含所有投票的数组,而是可以迭代的投票集合。我应该如何实施?

更新

请不要仅将 ActiveRecord 和 RDBMS 视为一种可能的存储。那么 Redis 作为存储和 LRANGE 之类的命令又如何呢?我对 Ruby 中解决此类问题的通用代码模式感兴趣。

ber*_*kes 5

来自Ruby on Rails指南:

User.all.each do |user|
  NewsLetter.weekly_deliver(user)
end
Run Code Online (Sandbox Code Playgroud)

效率很低。首先,您可能希望在数据库中进行大部分过滤。find_eachActiveRecord 提供了一个为此调用的方法:

User.find_each(:batch_size => 5000) do |user|
  NewsLetter.weekly_deliver(user)
end
Run Code Online (Sandbox Code Playgroud)

:batch_size参数允许获取数据片段而不是获取整个结果集。在大多数情况下非常有帮助。

但是,您可能不想首先对所有记录进行操作:

User.with_newsletter.each do |user| 
   NewsLetter.weekly_deliver(user)
end
Run Code Online (Sandbox Code Playgroud)

with_newsletter所谓的范围在哪里。