Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fetch "previous" document with mongoId

I have Images stored in mongoDB. They are sorted by "created_at".

Now, when I load a single item with Image.find("documentID") I want to access the document just before and the one just after this one, based on the created_at order.

For that, I have two methods and a default_scope in image.rb:

default_scope asc(:created_at)     

def previous_image
  self.class.last(:conditions => {:created_at.lt => created_at})
end

def next_image
  self.class.first(:conditions => {:created_at.gt => created_at})
end

Is there a native way in mongoDB to access the document before and after the current document?

Is there a better way to create such named scopes with mongoID in rails to access previous and next items, also considering performance (not querying three times for one image)?

Edit: The "previous_image" should use last, not first. That solves the bug of "skipping" items. The questions about the proper way to achive this remain, though.

like image 374
berkes Avatar asked Nov 28 '25 09:11

berkes


2 Answers

You may try something like this:

def previous_image mongoid
  self.class.find(:conditions => {:_id => {$lt: mongoid}}).sort({:_id=>-1}).limit(1)
end

def next_image mongoid
  self.class.find(:conditions => {:_id => {$gt: mongoid}}).sort({:_id=>1}).limit(1)
end

This approach utilizes sequentiality of Mongo ids.

like image 195
jhavrda Avatar answered Nov 29 '25 21:11

jhavrda


You could try something like the following, based on jhavdra's response, but rewritten for Mongoid syntax.

def previous_image
  self.class.where(:_id.lt => self._id).order_by([[:_id, :desc]]).limit(1).first
end

def next_image
  self.class.where(:_id.gt => self._id).order_by([[:_id, :asc]]).limit(1).first
end
like image 44
stef Avatar answered Nov 29 '25 22:11

stef