In Livedata and Minimongo, make falsey selectors match no documents,
instead of all documents. Same for {_id: undefined}. This is a
departure from most MongoDB drivers, but offers a safety belt around
selectors that are rarely useful and easy to accidentally create
programmatically.
For remove(), also protect against accidentally destroying an entire
collection when passing no args. To empty a collection, pass the
wildcard selector explicitly: foo.remove({});
For find(), keep the standard mongo behavior of returning all documents
when no selector is passed in by explicitly checking arguments.length.
This change also makes typical read cases cleaner, allowing:
x = foo.findOne(Session.get('foo_id'));
instead of
x = Session.get('foo_id') && foo.findOne(Session.get('foo_id'));
The new Collection API separates query handles from result sets. It
allows template iterators to only redraw changed objects instead of
entire result sets. This implementation also sets the stage for
minimongo indexes and better invalidation performance.
collection.find() now returns a Collection.Query handle. To retrieve
results we provide these methods on Collection.Query:
Iterators (encouraged way to access results):
* query.forEach(function (obj) { ... });
* results = query.map(function (obj) { ... });
Cursor-based retrieval (iterators are built on fetch):
* docs = query.fetch(maxlen); // return next [maxlen] (all) docs.
* doc = query.get(skip); // return next doc, skipping [skip] (0) docs.
Counter:
* length = query.count(); // number of results in query.
Live queries (replaces findLive):
* live_handle = query.observe({added: function (obj, idx) { ... },
removed: function (id, idx) { ... },
changed: function (obj, idx) { ... },
moved: function (obj, old_idx, new_idx) { ... }});
Convenience finders:
* doc = collection.findOne({color: 'red'});
* doc = collection.findOne(id_val);
On the client, calling forEach(), map(), fetch(), get(), or findOne()
inside an invalidation context will register a dependency on the entire
query result. Any change to any objects invalidates the context.
Calling count() inside an invalidation context will register a
dependency that only triggers if objects enter or leave the result set.
Calling observe() does not register a dependency.