Получение последнего документа с ограниченным результатом запроса Mongoid и .count () - PullRequest
5 голосов
/ 09 июня 2011

Я использую Mongoid для работы с MongoDB. Все хорошо, мне очень нравится и так далее. В моем приложении блога (контроллер сообщений, действие index) у меня есть этот код:

@posts = Post.without(:comments)
@posts = @posts.my_search(params[:s]) if params[:s]
@posts = @posts.order_by([:created_at, :desc])
@posts = @posts.where(:pid.lt => params[:p].to_i+1) if params[:p]
@posts = @posts.limit(items_per_page+1)

Часть с "где" - это реализация моего собственного метода нумерации страниц (позволяет публиковать результаты только в одном направлении, но без skip(), что я считаю плюсом). Теперь есть несколько небольших проблем, которые заставляют меня чувствовать себя некомфортно:

Чтобы моя нумерация страниц работала, мне нужно получить последнее сообщение в пределах этого лимита. Но когда я делаю @posts.last, я получаю последний документ всего запроса без ограничений. Хорошо, это странно, но не большая проблема. Кроме того, результаты запроса действуют почти как обычный массив, поэтому в данный момент я получаю последний элемент с @posts.pop (забавно, но он не удаляет документы) или @posts.fetch(-1)

У меня такое ощущение, что это не "правильный путь", и что-то должно быть более элегантным. Также @posts.count генерирует второй запрос точно так же, как первый (без ограничений), но только с "count", и мне это не нравится.

Если я сделаю последнюю строку похожей на

@posts = @posts.limit(items_per_page+1).to_ary

для преобразования результатов запроса в массив, все генерирует только один запрос (хорошо), но теперь @posts.count перестает сообщать о том, что мне нужно (общее количество документов без примененного ограничения) и ведет себя точно так же, как @posts.size - возвращает items_per_page+1 или меньше (плохо).

Итак, вот мои вопросы:

1) Как «правильно» получить последний документ результатов запроса в пределах заданного лимита?

2) Как получить общее количество документов с заданными условиями без генерации дополнительного запроса?

UPD:

3) @ posts.first генерирует дополнительный запрос, как его предотвратить и просто получить первый документ, прежде чем я переберу все документы?

1 Ответ

3 голосов
/ 09 июня 2011

Получение последнего документа:

Post.last 

Получение последнего документа с некоторыми другими запросами:

Post.order_by([:created_at, :desc]).last

Получение документов общего количества:

Post.order_by([:created_at, :desc]).count

Рекомендация:Просто используйте встроенную нумерацию страниц

@posts = Post.limit(10).paginate(:page=>pararms[:page])

позже:

<%= will_paginate @posts %>

По поводу дополнительных запросов - mongoid lazy загружает все:

@posts = Post.all #no query has been run yet
@posts.first #Ok, a query has finally been run because you are accessing the objects
...