A query selects a set of entities, then can step through the graph from that set: along reference fields, backwards to
whatever references them, or across relations. Building a query does no work. It compiles to a query AST, and runs only
when you pass it to db.query and read the result. org.dxos.echo#F-5.2
orderBy takes one or more orders, applied in turn. org.dxos.echo#F-5.3Order.property sorts by a
field; Order.created and Order.updated sort by timestamp; Order.natural keeps insertion order.
Order the query results.
Orders are specified in priority order. The first order will be applied first, etc.
Order.property orders by the current result shape's fields, so it works both before and after
an
aggregate
: before, by member (row) properties; after, by the flat record's fields
(any group or aggregate field — e.g. Order.property('lastMessageAt') reorders the groups by
that aggregate).
@param ― order - Order to sort the results.
@returns ― Query for the ordered results.
@performance ― O(k) in the number of orders; builds the AST without executing anything.
aggregate turns the results into records of named values: Aggregate.count, sum, min, max, group by a field,
items for the members of each group, and created, updated or time bucketed by a unit. It must be the last step that
selects data; only orderBy, limit, skip and from may follow it.
entries partition the
results into contiguous groups (one record each), keyed by the record field the group is named
after; with no group entries the entire input aggregates into a single record. Each declared
aggregate becomes a top-level field and can be ordered by with a following
orderBy
using
Order.property
.
Groups are ordered by the first occurrence of their key in the incoming stream, so a preceding
orderBy controls group order in the absence of a following one.
Aggregate.items
's own
order option is a separate, explicit per-group member ordering — pass it there rather than
relying on a preceding orderBy, whose only well-defined job once aggregate follows is
establishing initial group order. For example, message threads ordered by their most recent
message, each retaining up to 20 members newest-first:
@performance ― Async; executes the full query (index plus working set) on every call, not cached; O(n) in the data
the executor examines, not in the result count.
Without from, a query reads the database it runs on. from names the sources instead, with Scope: Scope.space() for
a space, Scope.registry() for the types and objects registered in code, and Scope.feed() for a
feed. from also takes a database, a feed object, or 'all-accessible-spaces'.
1
import {
import Filter
Filter,
import Query
Query,
import Scope
Scope,
import Type
Type } from'@dxos/echo';
2
3
// Types stored in the space, and types registered in code.
@performance ― O(k) in the number of scopes; builds the AST without executing anything.
from(
import Scope
Scope.
constspace: (options?: {
id?: string;
includeAllFeeds?: boolean;
}) =>SpaceScope
Scope targeting a space's automerge documents.
With no spaceId, targets the owning space — i.e. the space of whichever database
executes the query — so callers can reference "this space" without looking up its id.
@example
db.query(Filter.type(Person).from(Scope.space())); // owning space
db.query(Filter.type(Person).from(Scope.space({ id: otherSpaceId }))); // a specific space
@performance ― Async; executes the full query (index plus working set) on every call, not cached; O(n) in the data
the executor examines, not in the result count.
db.query returns a QueryResult. run() resolves with the results once. subscribe calls back each time the results
change, and { fire: true } also calls it straight away with the current results. org.dxos.echo#F-5.1
A query reads the objects on this device first and adds what the indexes and EDGE return. A subscriber can see results
arrive in more than one step. QueryResult.sources lists each source with its state: pending, answered or failed.
@performance ― Async; executes the full query (index plus working set) on every call, not cached; O(n) in the data
the executor examines, not in the result count.
@performance ― O(n) in the data examined: runs the full query and takes the first result; .limit(1) bounds the
work only where the executor applies the limit before scanning.
The console module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.
The module exports two specific components:
A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
A global console instance configured to write to process.stdout and
process.stderr. The global console can be used without importing the node:console module.
Warning: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the note on process I/O for
more information.
Example using the global console:
console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(newError('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr
Example using the Console class:
const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(newError('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
Prints to stdout with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to printf(3)
(the arguments are all passed to util.format()).