2011-06-09 11 views
5

Estoy usando Mongoid para trabajar con MongoDB. Todo está bien, me gusta mucho y todo eso. En mi blog de aplicaciones (controlador de mensajes, acción index) Tengo este código:Obteniendo el último documento del resultado de la consulta Mongoid limitada y .count()

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

La parte con "donde" es la ejecución de mi propio método de paginación (permite localizar a los resultados en una sola dirección, pero sin skip(), lo que considero un plus). Ahora, hay algunos pequeños problemas que me hacen sentir incómodo:

Para que mi paginación funcione, necesito obtener la última publicación dentro de ese límite. Pero cuando hago @posts.last obtengo el último documento de toda la consulta sin límite. Ok, esto es extraño, pero no es un gran problema. Aparte de eso, los resultados de la consulta actúan como casi-ordinaria-matriz, por lo que en este momento me estoy poniendo el último elemento con @posts.pop (divertido, pero no elimina ningún documento) o @posts.fetch(-1)

tengo la sensación de que esto no es "correcto" y hay algo más elegante. También @posts.count genera la segunda consulta exactamente igual a la primera (sin límite) pero con "conteo" solamente y no me gusta.

Si hago la última línea se parece a

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

para convertir los resultados de la consulta en una matriz, todo genera sólo una consulta (bueno), pero ahora @posts.count paradas informar lo que necesito (cantidad total de documentos sin límite aplicado) y se comporta exactamente como @posts.size - devuelve items_per_page+1 o menos (malo).

lo tanto, aquí están mis preguntas:

1) ¿Cuál es una manera "correcta" para obtener el último documento de resultados de la consulta dentro de límite dado?

2) ¿Cómo obtener la cantidad total de documentos con las condiciones dadas aplicadas sin generar consulta adicional?

UPD:

3) @ posts.first genera consulta adicional, cómo prevenirlo y acaba de obtener primer documento antes de iterar todos los documentos?

Respuesta

3

Conseguir el último documento:

Post.last 

Conseguir último documento con algunas otras consultas:

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

Obtener el total de documentos numéricos:

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

Recomendación: sólo tiene que utilizar el construido en el paginación

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

más tarde:

<%= will_paginate @posts %> 

En cuanto a las consultas adicionales - MongoId cargas perezoso todo:

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

Estás respondiendo a las preguntas que no pido :) Añadir .Limite (2) antes .last y ver cómo se comportará. Además, .count genera consultas adicionales y he estado preguntando cómo evitarlo. Eliminé will_paginate y kaminari porque no me gusta skip() y también porque no permiten "saltar" a la publicación específica en la acción del índice. Además, intente repetir con @ posts.each después de @ post.first, verá 2 consultas. –

+0

Si solo desea tener una consulta, debe insertar todo en una matriz. @posts = Post.whatever.all.to_a ... luego los @ posts.first y @ posts.last serán los métodos del enumerador Ruby y no los comandos mongoid. –

+0

Sí, escribí sobre eso en mi pregunta, pero @ posts.count genera una consulta adicional si la realizo antes de to_ary, y devuelve solo una cantidad limitada si la realizo después. ¿Hay alguna forma de realizar la consulta Y contar los resultados antes de limit()? –

Cuestiones relacionadas