| title | Selection |
|---|---|
| description | The Selection query type and its bulk update, replace, and delete methods, including how the update overloads resolve their return type. |
| mode | reference |
The Selection<T> class represents a set of documents and provides bulk mutation methods. It extends Stream<T>, so it also has every transformation, filtering, and aggregation method.
class Selection<T> extends Stream<T> {
update<U>(
document: (val: ValueProxy<T>) => U,
): ExtractType<U> extends DeepPartial<T> ? Query<number> : never;
update(document: DeepPartial<T> & object): Query<number>;
replace(document: DeepPartial<T> & object): Query<number>;
delete(): Query<number>;
}The updater overload comes first and the document overload last:
- A function argument resolves to the updater overload. It returns
Query<number>when the type the updater builds fitsDeepPartial<T>, andneverotherwise. - An object argument resolves to the document overload, which returns
Query<number>. - An argument typed
anyresolves to the updater overload, and the conditional givesnever. The result has no.run()and cannot be awaited for a count. Give the argument a real type. - A type-level read such as
ReturnType<typeof table.update>takes the last overload and readsQuery<number>.
Table methods such as getAll() and between() produce selections. So does a chained stream operation such as filter():
import { Schema } from "@antelopejs/interface-database";
const schema = Schema.get("myapp");
if (!schema) throw new Error("Define the myapp schema first");
const users = schema.instance().table("users");
// Selection from getAll
const admins = users.getAll("admin", "role");
// Selection from between
const recentUsers = users.between(
"createdAt",
new Date("2024-01-01"),
new Date(),
);The update method changes the matching documents with the given partial data. Fields that the update object leaves out stay unchanged. It returns the number of modified documents.
// Update with a partial object
const count = await users
.getAll("inactive", "status")
.update({ status: "active" });
console.log(`Activated ${count} users`);
// Update with a function for computed values
await users.getAll("active", "status").update((user) => ({
loginCount: user.key("loginCount").add(1),
}));The replace method replaces each whole document with the given data. Unlike update, it removes every field that the replacement leaves out.
const count = await users.getAll("user-123").replace({
_id: "user-123",
name: "New Name",
email: "new@example.com",
role: "user",
});
console.log(`Replaced ${count} documents`);The delete method removes every document in the selection and returns the number of deleted documents.
const count = await users.getAll("inactive", "status").delete();
console.log(`Deleted ${count} inactive users`);Selection extends Stream, so it inherits every stream operation. These are grouped by purpose:
- Transformation:
map(),pluck(),without() - Filtering:
filter() - Aggregation:
count(),sum(),avg(),min(),max() - Joining:
join(),joinInner(),lookup() - Ordering:
orderBy(),slice(),nth() - Grouping:
group() - Deduplication:
distinct() - Fields and fallbacks:
key(),default() - Combining and typing:
union(),cast() - Change feeds:
changes()
See Stream for the details of these methods.