Skip to content

Scoping by attribute fields

outoftime edited this page Sep 13, 2010 · 8 revisions

The basics of scoping

Scoping in Sunspot is the equivalent of placing conditions on a database query – values against which to compare fields are passed in and processed verbatim. Scopes in Sunspot’s DSL are built using the with method:


Sunspot.search(Post) do
  with(:published_at).less_than(Time.now)
end

This will send a query to Sunspot that is roughly the equivalent of the MySQL query:


SELECT `posts`.* FROM `posts` WHERE `published_at` < NOW();

The argument to the with method is always the name of an attribute field (e.g., one defined using a type other than text). The chained method is the name of a restriction; the available restrictions are:

equal_to
Match all documents for whom this field contains exactly this value. For multi-valued fields, one of the values must match exactly (this pattern extends to all types of restrictions).
less_than
Match all documents for whom this field contains a value less than or equal to the given value.
greater_than
Match all documents for whom this field contains a value greater than or equal to the given value.
between
Match all documents for whom this field is between the values in the given range, inclusive. Value should be a Range or another object that responds to first and last.
any_of
Match all documents for whom this field contains any of the given collection of values. Value should be an Array or other Enumerable.
all_of
Match all documents for whom this field contains all of the given collection of values. This is only meaningful when applied to multi-valued fields. Value should be an Array or other Enumerable.

Shorthand restrictions

Sunspot also provides shorthand restrictions, wherein a second argument is passed to with; the restriction type is determined based on the class of the second argument:

- If an Array is passed, an any_of restriction is created.
- If a Range is passed, a between restriction is created.
- Otherwise, an equal_to restriction is created.

For example, the following pairs of restriction calls are equivalent:


with(:blog_id, 1)
with(:blog_id).equal_to(1)

with(:average_rating, 3.0..5.0)
with(:average_rating).between(3.0..5.0)

with(:category_ids, [1, 3, 5])
with(:category_ids).any_of([1, 3, 5])

Combining restrictions

The simplest way to combine restrictions is to specify more than one within the search block; this will match documents to whom all of the restrictions apply:


Sunspot.search(Post) do
  with(:published_at).less_than(Time.now)
  with(:blog_id, 1)
end

The above will match all documents whose published date is in the past, and whose blog_id is 1.