Ecto.Query

Parsed documentation:
View on GitHub
Provides the Query DSL.

Queries are used to retrieve and manipulate data in a repository
(see `Ecto.Repo`). Although this module provides a complete API,
supporting expressions like `where/3`, `select/3` and so forth,
most of the times developers need to import only the `from/2`
macro.

    # Imports only from/1 and from/2 from Ecto.Query
    import Ecto.Query, only: [from: 2]

    # Create a query
    query = from w in Weather,
          where: w.prcp > 0,
         select: w.city

    # Send the query to the repository
    Repo.all(query)

## Composition

Ecto queries are composable. For example, the query above can
actually be defined in two parts:

    # Create a query
    query = from w in Weather, where: w.prcp > 0

    # Extend the query
    query = from w in query, select: w.city

Keep in mind though the variable names used on the left-hand
side of `in` are just a convenience, they are not taken into
account in the query generation.

Any value can be used on the right-side of `in` as long as it
implements the `Ecto.Queryable` protocol.

## Query expressions

Ecto allows a limitted set of expressions to be used inside queries:

  * Comparison operators: `==`, `!=`, `<=`, `>=`, `<`, `>`
  * Boolean operators: `and`, `or`, `not`
  * Inclusion operator: `in/2`
  * Search functions: `like/2` and `ilike/2`
  * Null check functions: `is_nil/1`
  * Aggregates: `count/1`, `avg/1`, `sum/1`, `min/1`, `max/1`

Futhermore, Ecto allows the following literals inside queries:

  * Integers: `1`, `2`, `3`
  * Floats: `1.0`, `2.0`, `3.0`
  * Booleans: `true`, `false`
  * Binaries: `<<1, 2, 3>>`
  * Strings: `"foo bar"`, `~s(this is a string)`
  * Arrays: `[1, 2, 3]`, `~w(interpolate words)`
  * UUIDs: `uuid("0123456789abcdef")`

External values and Elixir expressions can be injected into a query
expression with `^`:

    def with_minimum(age, height_ft) do
        from u in User,
      where: u.age > ^age and u.height > ^(height_ft * 3.28)
    end

    with_minimum(18, 5.0)

Finally, Ecto provides two conveniences for dynamically generating
queries. The first is the `field/2` function which allows developers
to dynamically choose a field to query:

    def at_least_four(doors_or_tires) do
        from c in Car,
      where: field(u, ^doors_or_tires) >= 4
    end

In the example above, both `at_least_four(:doors)` and `at_least_four(:tires)`
would be valid calls as the field is dynamically inserted.

The other convenience is called fragments which allows developers to send
any expression to the database via the `fragment(...)` function:

    def unpublished_by_title(title)
      from p in Post,
        where: is_nil(p.published_at) and
               fragment("downcase(?) == ?", p.title, ^title)
    end

Fragments are sent directly to the database while also allowing field names
like `p.title` and values like `^title` to be interpolated.

## Casting

Ecto is able to cast interpolated values in queries:

    age = "1"
    Repo.all(from u in User, where: u.age > ^age)

The example above will work even if `age` is tagged as an :integer
in the User module because Ecto is able to cast values. In case a
value cannot be cast, `Ecto.CastError` is raised.

It is important to keep in mind that Ecto cannot cast nil values in
queries. Passing nil automatically causes the query to fail.

## Query expansion

In all examples so far, we have used the **keywords query syntax** to create
a query. Our first example:

    import Ecto.Query

       from w in Weather,
     where: w.prcp > 0,
    select: w.city

Simply expands to the following **query expressions**:

    from(w in Weather) |> where([w], w.prcp > 0) |> select([w], w.city)

Which then expands to:

    select(where(from(w in Weather), [w], w.prcp > 0), [w], w.city)

This module documents each of those macros, providing examples both
in the keywords query and in the query expression formats.
No suggestions.
Please help! Open an issue on GitHub if this assessment is incorrect.