2

我试图用 DataMapper 选择随机数据集,但似乎没有这样的功能支持。

例如,我有一组数据:

+-------------------+
| ID | Name | Value |
+-------------------+
| 1  | T1   | 123   |
| 2  | T2   | 456   |
| 3  | T3   | 789   |
| 4  | T4   | 101   |
| ----------------- |
| N  | Tn   | value |

可能有很多数据,超过 100k 行。

我需要将数据映射到对象:

class Item
  include DataMapper::Resource
  property :id, Serial
  property :name, String
  property :value, String
end

所以,问题是:如何从表中选择随机数据?

SQL 中的类似查询将是:

SELECT id, name, value FROM table ORDER BY RAND() LIMIT n;
4

3 回答 3

6

OP 之后很长一段时间,但由于这是谷歌第一次点击“datamapper random row”......

使用纯 DataMapper,并且不假设连续 ID 等,您可以执行以下操作:

Item.first(:offset => rand(Item.count))

这导致查询:

SELECT COUNT(*) FROM `items`
SELECT <fields> FROM `items` ORDER BY `id` LIMIT 1 OFFSET <n>

如果您更喜欢单个查询,但可能会降低速度,您可以执行以下操作:

Item.all.sample

结果:

SELECT <fields> FROM `items` ORDER BY `id`

显然,如果需要,可以将其包装在事务中。

于 2012-01-29T02:20:18.593 回答
2

我通常不在乎从字面上检索随机记录。在这种情况下,我使用了稍微不同的范例。

  1. ORDER BY value // 或 value mod some number // 你也可以使用 name,或者 name 上的一些函数
  2. 选择限制 n 偏移 k

其中 k 是您的代码中生成的小于 Nn 的随机数。对于大多数情况来说,足够随机,即使记录在您用于 ORDER BY 的内容中有些连续。

于 2009-06-12T20:22:32.777 回答
1

您可以生成一个随机数 x < number_of_rows,然后获取该 ID。

您也可以尝试直接输入 SQL,如下所示:

find_by_sql(<<-SQL
    SELECT `id`, `name`, `value` FROM table ORDER BY RAND() LIMIT n;
SQL, :properties => property_set)

但是,您需要指定 :properties,以便它与您的属性集进行映射。

于 2009-06-12T18:58:11.793 回答