Docs Menu
Docs Home
/ / /
Mongoid
/

Modify Query Results

On this page

  • Overview
  • Sample Data
  • Return Specified Fields
  • Include Fields
  • Exclude Fields
  • Sort Results
  • Paginate Results
  • Limit Number of Results
  • Skip Results
  • Generate Batches of Results
  • Additional Information

In this guide, you can learn how to customize the way that Mongoid returns results from queries. MongoDB allows you to perform the following actions to modify the way that results appear:

  • Return Specified Fields

  • Sort Results

  • Paginate Results

The examples in this guide use the Band model, which represents a band or musical group. The definition of the Band model might be different for each section to demonstrate different query functionalities. Some sections also use the Manager model, which represents a person who manages a given band, or the Tour model, which represents live performances by a given band.

In MongoDB, projection is the process of specifying fields to include or exclude from results. Mongoid provides the following operators to project fields:

  • only: Specifies fields to include

  • without: Specifies fields to exclude

The only method retrieves only the specified fields from the database.

The following code returns only the name field from documents in which the value of the members field is 4:

Band.where(members: 4).only(:name)

Note

_id Field

In MongoDB, the _id field is included in results even if you do not explicitly include it.

If you attempt to reference attributes that have not been loaded, Mongoid raises a Mongoid::Errors::AttributeNotLoaded error.

You can also use the only method to include fields from embedded documents.

Consider that the Band model embeds multiple Tour objects. You can project fields from the Tour model such as year, as shown in the following code:

bands = Band.only(:name, 'tours.year')

Then, you can access the embedded fields from the returned documents:

# Returns the first Tour object from
# the first Band in the results
bands.first.tours.first

You can pass fields of referenced associations to the only method, but the projection is ignored when loading the embedded objects. Mongoid loads all fields of the referenced associations. For example, when you access the embedded Tour object as shown in the preceding code, Mongoid returns the complete object, not just the year field.

Note

If you are connected to a deployment running MongoDB 4.4 or later, you cannot specify an association and its fields in a projection in the same query.

If a document contains has_one or has_and_belongs_to_many associations, and you want Mongoid to load those associations when you call the only method, you must include the fields with foreign keys in the list of attributes.

In the following example, the Band and Manager models have a has_and_belongs_to_many association:

class Band
include Mongoid::Document
field :name, type: String
has_and_belongs_to_many :managers
end
class Manager
include Mongoid::Document
has_and_belongs_to_many :bands
end

The following code demonstrates how Mongoid can load the associated Manager objects if you include the manager_ids field:

# Returns null
Band.where(name: 'Astral Projection').only(:name).first.managers
# Returns the first Manager object
Band.where(name: 'Astral Projection').only(:name, :manager_ids).first.managers

You can explicitly exclude fields from results by using the without method.

The following code excludes the year field from returned Band objects:

Band.where(members: 4).without(:year)

Important

_id Field

Mongoid requires the _id field for various operations, so you cannot exclude the _id field or the id alias from results. If you pass _id or id to the without method, Mongoid ignores it.

You can specify the order in which Mongoid returns documents by using the order and order_by methods.

These methods accept a hash that indicates which fields to order the documents by, and whether to use an ascending or descending order for each field.

You can specify the sort direction by using integers, symbols, or strings. We recommend using the same sorting syntax throughout your application for consistency. The following list provides each syntax and shows how to sort on the name and year fields:

  • Integers 1 (ascending) and -1 (descending)

    • Example: Band.order(name: 1, year: -1)

  • Symbols :asc and :desc

    • Example: Band.order(name: :asc, year: :desc)

  • Strings "asc" and "desc"

    • Example: Band.order_by(name: "asc", year: "desc")

The order method also accepts the following sort specifications:

  • Array of two-element arrays:

    • Strings

      • Example: Band.order([['name', 'asc'], ['year', 'desc']])

    • Symbols

      • Example: Band.order([[:name, :asc], [:year, :desc]])

  • asc and desc methods on symbols

    • Example: Band.order(:name.asc, :year.desc)

  • SQL syntax

    • Example: Band.order('name asc', 'year desc')

Tip

Instead of using order or order_by, you can also use the asc and desc methods to specify sort orders:

Band.asc('name').desc('year')

When you chain sort specifications, the first call defines the first sorting order and the newest call defines the last sorting order after the previous sorts have been applied.

Note

Sorting in Scopes

If you define a default scope on your model that includes a sort specification, the scope sort takes precedence over the sort specified in a query, because the default scope is evaluated first.

Mongoid provides the limit, skip, and batch_size pagination methods that you can use on Criteria objects. The following sections describe how to use these operators.

You can use the limit method to limit the number of results that Mongoid returns.

The following code retrieves a maximum of 5 documents:

Band.limit(5)

Note

Alternatively, you can use the take method to retrieve a specified number of documents from the database:

Band.take(5)

You can skip a specified number of results by using the skip method, or its alias offset.

If you chain a limit call to skip, the limit is applied after documents are skipped, as demonstrated in the following example:

Band.skip(2).limit(5)
# Skips the first two results and returns
# the following five results

Tip

When performing pagination, use skip on sorted results to ensure consistent results.

The following code skips the first 3 documents when returning results:

Band.skip(3)
# Equivalent
Band.offset(3)

When executing large queries and when iterating over query results by using an enumerator method such as Criteria#each, Mongoid automatically uses the MongoDB getMore command to load results in batches. The default batch size is 1000, but you can set a different value by using the batch_size method.

The following code sets the batch size to 500:

Band.batch_size(500)

To learn more about constructing queries, see the Specify a Query guide.

To learn about Mongoid data modeling, see the Model Your Data guides.

Back

Asynchronous Queries