Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting the last document of limited Mongoid query result and .count()

I'm using Mongoid to work with MongoDB. Everything is fine, I like it very much and so on. In my blog application (posts controller, index action) I have this code:

@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)

The part with "where" is implementation of my own pagination method (allows to page results in one direction only, but without skip(), what I consider a plus). Now, there are few small problems that make me feel uncomfortable:

For my pagination to work I need to get the last post within that limit. But when I do @posts.last I'm getting last document of the whole query without limit. Ok, this is strange, but not a big problem. Other than that, query results act like almost-ordinary-array, so at this moment I'm getting the last element with @posts.pop (funny, but it doesn't remove any documents) or @posts.fetch(-1)

I have a feeling that this isn't "right way" and there mush be something more elegant. Also @posts.count generates second query exactly the same as first one (without limit) but with "count" only and I don't like it.

If I make the last line look like

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

to convert query results into array, everything generates only one query (good), but now @posts.count stops reporting what I need (total amount of documents without limit applied) and behaves exactly like @posts.size - it returns items_per_page+1 or less (bad).

So, here are my questions:

1) What is a "correct" way to get the last document of query results within given limit?

2) How to get total amount of documents with given conditions applied without generating additional query?

UPD:

3) @posts.first generates additional query, how to prevent it and just get first document before I iterate all documents?

like image 589
Jake Jones Avatar asked Oct 24 '22 09:10

Jake Jones


1 Answers

Getting the last document:

Post.last 

Getting last document with some other queries:

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

Getting total number documents:

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

Recommendation: Just use the built in pagination

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

later:

<%= will_paginate @posts %>

Regarding the additional queries -- mongoid lazy loads everything:

@posts = Post.all #no query has been run yet
@posts.first #Ok, a query has finally been run because you are accessing the objects
like image 115
Jesse Wolgamott Avatar answered Oct 27 '22 10:10

Jesse Wolgamott