Skip to content

Latest commit

 

History

History
109 lines (81 loc) · 3.62 KB

3.selection.md

File metadata and controls

109 lines (81 loc) · 3.62 KB
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 definition

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 fits DeepPartial<T>, and never otherwise.
  • An object argument resolves to the document overload, which returns Query<number>.
  • An argument typed any resolves to the updater overload, and the conditional gives never. 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 reads Query<number>.

Create a selection

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(),
);

Update documents

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),
}));

Replace documents

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`);

Delete 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`);

Inherited methods

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.