Mongo finders and criteria

2019-05-28 13:44发布

问题:

I use MongoDB in my rails application with Mongoid mapper. But I don't understand finders and criteria of querying. For example in mongoid documentaion in section Finders is query Model.all, but if I use that(for example User.all), console return criteria and not the result:

 => #<Mongoid::Criteria
  selector: {},
  options:  {},
  class:    User,
  embedded: false>

But if I use finder Model.first or Model.last, console return specific result. (User.first return specific user, with its fields, as :email, :username and other). Why Model.all wrote in documentation as finders? And what I need doing if I need get all Users or for example Posts?

回答1:

You can treat the criteria object as array. Finders return a criteria object because criteria is chainable in mongoid. That is, you can do something like:

users = User.where(:activated => true)
users = users.where(:created_at.gte => Time.now - 1.week) unless params[:recent].blank?
users = users.where(:gender => params[:gender].downcase) if %w[m f].include?(params[:gender].downcase

Anytime you use any methods which are not defined in Criteria, mongoid will actually run the query and fetch the results and treat them as array. If you specifically want the results to be returned as array, you can always call User.all.to_a. But keep in mind that following two are mostly equivalent:

User.all.each {|u| puts u.id}
User.all.to_a.each {|u| puts u.id}

But there is one issue with the later, it will fetch all the documents in memory once and can lead to too much of memory consumption. However, first one uses Mongodb cursors to fullest and only loads documents yielded by cursor, means controlled memory usage.