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.