Rails: получить список случайных элементов из базы данных MySQL - PullRequest
1 голос
/ 10 августа 2010

У меня есть несколько тегов для каждого сообщения. (Очень похоже на SO). Я хочу 20 случайных предметов, не повторяющихся.

Я знаю, что могу использовать Tags.all.rand (и повторить 10 раз), однако, это не гарантирует уникальность.

И я знаю, что мог бы использовать SQL-запрос, но поскольку моя среда разработки использует sqlite в качестве базы данных и MySQL в рабочей среде, ORDER by RAND не будет работать для обоих.

Помимо двух разных запросов (Dev & Prod), что еще я могу сделать?

Спасибо

Ответы [ 3 ]

2 голосов
/ 10 августа 2010

Ответ Райана делает это, но идет с ошибкой.Если ваш набор данных очень большой, то: order => "RAND ()" нецелесообразно (запрос будет выполняться очень медленно).Существует два альтернативных метода: сначала получить все идентификаторы ваших элементов, выбрать 20 случайным образом, а затем выбрать эти строки или получить количество элементов в БД, выбрать один со случайным смещением и повторить (сначала выберите смещения, чтобыгарантия не повторяется).

Подробнее об этом читайте в книге SQL Antipatterns , где эта глава является халявой.

Кстати: при использовании Ruby 1.8+ или Rails 2.3+(Я полагаю) есть метод Array # sample , который позволит вам выбрать n элементов rand без повторения, как в вашем первоначальном подходе.

2 голосов
/ 10 августа 2010

Вы можете выбрать случайную выборку из 20 тегов, используя:

Tag.all.sort_by {rand}[0..19]

(Спасибо Чубасу за это простое решение!)

Недостатком этого является то, что он будет неэффективным для больших наборов данных. Вы можете улучшить это, выбрав только идентификаторы:

Tag.all(:select => :id).map(&:id).sort_by{rand}[0..19]
2 голосов
/ 10 августа 2010

Почему вы используете две разные базы данных для разработки и производства? Это может привести к проблемам в дальнейшем. Возьмем, к примеру, то, что произошло с нами недавно, один из наших разработчиков использовал MySQL и использовал специальный синтаксис LIKE только для MySQL, который не работал в нашей производственной базе данных PostgreSQL.

Мораль истории: если вы используете что-то другое для разработки, тестирования и / или производства: вы делаете это неправильно.

Далее: Чтобы получить случайные элементы в MySQL, вы можете сделать: Tag.all(:order => "RAND()", :limit => 10).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...