<commit_before>=======
Queries
=======

.. default-domain:: mongodb

.. contents:: On this page
   :local:
   :backlinks: none
   :depth: 2
   :class: singlecol

One of MongoDB's greatest features is its ability to execute dynamic
queries, provided through a familiar Arel-style DSL.

Queries
-------

All queries in Mongoid are ``Mongoid::Criteria``, which is a chainable and
lazily evaluated wrapper to a MongoDB dynamic query. Criteria only
touch the database when they need to, for example on iteration of the
results, and when executed wrap a cursor in order to keep memory
management and performance predictable.

Queryable DSL
*************

Query methods are available off a ``Mongoid::Criteria`` object
*as well as* off the model's class.

.. code-block:: ruby

  Band.where(name: "<NAME>")
  Band.
    where(:founded.gte => "1980-1-1").
    in(name: [ "Tool", "Deftones" ]).
    union.
    in(name: [ "Melvins" ])

With each chained method on a criteria, a newly cloned criteria
is returned with the new query added. This is so that with scoping
or exposures, for example, the original queries are unmodified
and remain reusable.

elem_match
``````````

This matcher finds documents with array fields where one of the array values
matches all of the conditions. For example:

.. code-block:: ruby

  class Band
    include Mongoid::Document
    field :name, type: String
    field :tours, type: Array
  end

  aerosmith = Band.create!(name: 'Aerosmith', tours: [
    {city: 'London', year: 1995},
    {city: 'New York', year: 1999},
  ])

  Band.elem_match(tours: {city: 'London'}).to_a # => [aerosmith]

``elem_match`` also works with embedded associations:

.. code-block:: ruby

  class Band
    include Mongoid::Document
    field :name, type: String
    embeds_many :tours
  end

  class Tour
    include Mongoid::Document
    field :city, type: String
    field :year, type: Integer
    embedded_in :band
  end

  dm = Band.create!(name: 'Depeche Mode')
  aerosmith = Band.create!(name: 'Aerosmith')
  Tour.create!(band: aerosmith, city: 'London', year: 1995)
  Tour.create!(band: aerosmith, city: 'New York', year: 1999)

  Band.elem_match(tours: {city: 'London'}).to_a # => [aerosmith]

``elem_match`` does not work with non-embedded associations because MongoDB
does not have joins - the conditions would be added to the collection
that is the source of a non-embedded association rather than the collection
of the association's target.

``elem_match`` can also be used with recursively embedded associations,
as the following example shows:

.. code-block:: ruby

  class Tag
    include Mongoid::Document
    field :name, type: String
    recursively_embeds_many
  end

  root = Tag.create!(name: 'root')
  sub1 = Tag.new(name: 'sub1', child_tags: [Tag.new(name: 'subsub1')])
  root.child_tags << sub1
  root.child_tags << Tag.new(name: 'sub2')
  root.save!

  Tag.elem_match(child_tags: {name: 'sub1'}).to_a # => [root]

  root.child_tags.elem_match(child_tags: {name: 'subsub1'}).to_a # => [sub1]

only
````

This method retrieves only the specified fields from the database.

.. code-block:: ruby

  class Band
    include Mongoid::Document
    
    field :name, type: String
    field :label, type: String
    
    embeds_many :tours
  end

  class Tour
    include Mongoid::Document
    
    field :city, type: String
    field :year, type: Integer
    
    embedded_in :band
  end<commit_msg>Add a "projection" keyword to the query doc (#4748)<commit_after>=======
Queries
=======

.. default-domain:: mongodb

.. contents:: On this page
   :local:
   :backlinks: none
   :depth: 2
   :class: singlecol

One of MongoDB's greatest features is its ability to execute dynamic
queries, provided through a familiar Arel-style DSL.

Queries
-------

All queries in Mongoid are ``Mongoid::Criteria``, which is a chainable and
lazily evaluated wrapper to a MongoDB dynamic query. Criteria only
touch the database when they need to, for example on iteration of the
results, and when executed wrap a cursor in order to keep memory
management and performance predictable.

Queryable DSL
*************

Query methods are available off a ``Mongoid::Criteria`` object
*as well as* off the model's class.

.. code-block:: ruby

  Band.where(name: "<NAME>")
  Band.
    where(:founded.gte => "1980-1-1").
    in(name: [ "Tool", "Deftones" ]).
    union.
    in(name: [ "Melvins" ])

With each chained method on a criteria, a newly cloned criteria
is returned with the new query added. This is so that with scoping
or exposures, for example, the original queries are unmodified
and remain reusable.

elem_match
``````````

This matcher finds documents with array fields where one of the array values
matches all of the conditions. For example:

.. code-block:: ruby

  class Band
    include Mongoid::Document
    field :name, type: String
    field :tours, type: Array
  end

  aerosmith = Band.create!(name: 'Aerosmith', tours: [
    {city: 'London', year: 1995},
    {city: 'New York', year: 1999},
  ])

  Band.elem_match(tours: {city: 'London'}).to_a # => [aerosmith]

``elem_match`` also works with embedded associations:

.. code-block:: ruby

  class Band
    include Mongoid::Document
    field :name, type: String
    embeds_many :tours
  end

  class Tour
    include Mongoid::Document
    field :city, type: String
    field :year, type: Integer
    embedded_in :band
  end

  dm = Band.create!(name: 'Depeche Mode')
  aerosmith = Band.create!(name: 'Aerosmith')
  Tour.create!(band: aerosmith, city: 'London', year: 1995)
  Tour.create!(band: aerosmith, city: 'New York', year: 1999)

  Band.elem_match(tours: {city: 'London'}).to_a # => [aerosmith]

``elem_match`` does not work with non-embedded associations because MongoDB
does not have joins - the conditions would be added to the collection
that is the source of a non-embedded association rather than the collection
of the association's target.

``elem_match`` can also be used with recursively embedded associations,
as the following example shows:

.. code-block:: ruby

  class Tag
    include Mongoid::Document
    field :name, type: String
    recursively_embeds_many
  end

  root = Tag.create!(name: 'root')
  sub1 = Tag.new(name: 'sub1', child_tags: [Tag.new(name: 'subsub1')])
  root.child_tags << sub1
  root.child_tags << Tag.new(name: 'sub2')
  root.save!

  Tag.elem_match(child_tags: {name: 'sub1'}).to_a # => [root]

  root.child_tags.elem_match(child_tags: {name: 'subsub1'}).to_a # => [sub1]

only
````

This method retrieves only the specified fields from the database. This
operation is sometimes called "projection".

.. code-block:: ruby

  class Band
    include Mongoid::Document
    
    field :name, type: String
    field :label, type: String
    
    embeds_many :tours
  end

  class Tour
    include Mongoid::Document
    
    field :city, type: String
    field :year, type: Integer
    
    embedded_in :band
  end
{'fraction_non_alphanumeric': 0.11581227436823105, 'fraction_numerical': 0.009530685920577618, 'mean_word_length': 3.7244201909959074, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1345803', 'n_tokens_mistral': 2260, 'n_tokens_neox': 2111, 'n_words': 793}