Skip to content

Commit

Permalink
Update readme with section on ordered/unordered
Browse files Browse the repository at this point in the history
  • Loading branch information
etyp committed Sep 10, 2018
1 parent 757d43b commit 6c5e53b
Showing 1 changed file with 33 additions and 10 deletions.
43 changes: 33 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,37 +23,60 @@ Installation
meteor add peerlibrary:reactive-mongo
```

Polling vs. Oplog inside autoruns
Invalidating computations on Ordered vs. Unordered cursors
------------
A common use case for server autoruns is using a `findOne` to do a reactive join. Meteor's server-side `findOne` is simply a `find(selector, { limit: 1 }).fetch()[0]` [under the hood](https://github.com/meteor/meteor/blob/devel/packages/mongo/mongo_driver.js#L784). [Because Meteor Oplog does not support](https://galaxy-guide.meteor.com/apm-optimize-your-app-for-oplog.html#Limit-Without-Sort) `limit` without `sort`, calling `Collection.findOne(someId)` in a server autorun will default to using polling.
In Meteor, there's a concept of `ordered` cursors. If a cursor is `ordered`, then when the order of the documents in the result set changes, the computation will be invalidated and the `autorun` will re-run.

By default, this package will use an ordered cursor if a `sort` is present in the query. If no `sort` is specified, it will use an unordered cursor.

If you'd like queries inside a server autorun to use Oplog, you'll need to specify a sort for your `findOne` like so:
To override the defualt functionality, you can explicitly force or un-force `ordered` by passing an `ordered` option to your `find`:

```
// Server code
// Will use oplog
// Will use ordered since a sort is present
Tracker.autorun(() => {
Collection.findOne(someId, { sort: { _id: 1 } });
Posts.find({ topic: 'news' }, { sort: { name: 1 } }).fetch();
});
// Will use polling because no sort is specified
// Will use unordered since no sort is present
Tracker.autorun(() => {
Collection.findOne(someId);
Posts.find({ topic: 'news' }).fetch();
});
// Will not use ordered since the option is forced to "false"
Tracker.autorun(() => {
Posts.find({ topic: 'news' }, { sort: { name: 1 }, ordered: false }).fetch();
});
// Will use ordered since the option is forced to "true"
Tracker.autorun(() => {
Posts.find({ topic: 'news' }, ordered: true }).fetch();
});
```

Alternatively, if you want to force polling while using a `sort` and `limit` (since [depending on your use case, it could be more efficient](https://blog.meteor.com/tuning-meteor-mongo-livedata-for-scalability-13fe9deb8908)), you can add the disableOplog option to the find:
Polling vs. Oplog inside autoruns
------------
A common use case for server autoruns is using a `findOne` to do a reactive join. Meteor's server-side `findOne` is a `find(selector, { limit: 1 }).fetch()[0]` [under the hood](https://github.com/meteor/meteor/blob/devel/packages/mongo/mongo_driver.js#L784). [Because Meteor Oplog does not support](https://galaxy-guide.meteor.com/apm-optimize-your-app-for-oplog.html#Limit-Without-Sort) `limit` without `sort`, calling `Collection.findOne(someId)` in a server autorun will default to using polling.


If you'd like queries inside a server autorun to use Oplog, you'll need to specify a sort for your `findOne` **and** pass `ordered: false` to use unordered cursor:

```
// Server code
// Will use polling
// Will use oplog since it has sort, limit, and is unordered
Tracker.autorun(() => {
Collection.find({ topic: 'Programming' }, { sort: { title: 1 }, limit: 50, disableOplog: true });
Collection.findOne(someId, { sort: { _id: 1 }, ordered: false });
});
// Will use polling because a limit (from findOne) but no sort is specified
Tracker.autorun(() => {
Collection.findOne(someId);
});
```


Acknowledgments
---------------

Expand Down

0 comments on commit 6c5e53b

Please sign in to comment.