The get()
method executes a query that is expected to produce at most one record.
For such a query, get() is preferable to begin(): it is more efficient, because it doesn't
create an iterator, and to the reader of your code it clearly signals
that multiple records are not expected.
For any query q with value type T,
q.get()
returns a boost::optional<T>.
q produces no records, q.get() returns boost::none.
q produces exactly one record, q.get() returns that record, wrapped in
a boost::optional.
q produces more than one record, q.get() treats it as an error and throws
multi_row_exception.
(Perhaps you meant to call q.limit(1).get().)
One common use case is simple record retrieval by a unique key, e.g. a primary key:
extern const serial bridge_on_the_river_quince_id; const boost::optional<movie> botrq = movies .where(movies->id==bridge_on_the_river_quince_id) .get();
or retrieval of part of such a record:
const boost::optional<std::string> botrq_title = movies .where(movies->id==bridge_on_the_river_quince_id) .select(movies->title) .get();
In these cases we know that the query will produce at most one output,
because the where(...) clause is applied directly to a table,
and tests for an exact match of a unique key. In other cases our knowledge
may be indirect. E.g., recall this definition
of local_hits:
const query<movie> local_hits = local_movies .distinct() .order(- score(local_movies->id)) .limit(n);
With a moment's thought we can prove that this query never produces two
movies with the same
id. Therefore it is safe
to “look up” an id
in local_hits, just as
we did in movies:
const boost::optional<movie> local_hit_botrq = local_hits .where(local_hits->id==bridge_on_the_river_quince_id) .get();
or:
const boost::optional<std::string> local_hit_botrq_title = local_hits .where(local_hits->id==bridge_on_the_river_quince_id) .select(local_hits->title) .get();