In Meteor Mongo, how to specify the readPref to primary|secondary in Meteor Mongo Query.
Read preference describes how MongoDB clients route read operations to the members of a replica set. click to enlarge. By default, an application directs its read operations to the primary member in a replica set (i.e. read preference mode "primary").
Replica set members can lag behind the primary due to network congestion, low disk throughput, long-running operations, etc. The read preference maxStalenessSeconds option lets you specify a maximum replication lag, or "staleness", for reads from secondaries.
You can force a replica set member to become primary by giving it a higher members[n]. priority value than any other member in the set. Optionally, you also can force a member never to become primary by setting its members[n]. priority value to 0 , which means the member can never seek election as primary.
I hope the following provides a better understanding of the relationship between Meteor and Mongo.
Meteor provides you with the full mongo functionality. However for comfort it provides a wrapped API of a mongo collection that integrates best with the Meteor environment. So if you import Mongo via
import { Mongo } from 'meteor/mongo'
you primarily import the wrapped mongo collection where operations are executed in a Meteor fiber. The cursor that is returned by queries of these wrapped collections are also not the "natural" cursors but also wrapped cursors to be Meteor optimized.
If you try to access a native feature on these instances that is not implemented you will receive an error. In your case:
import { Meteor } from 'meteor/meteor';
import { Random } from 'meteor/random';
const ExampleCollection = new Mongo.Collection('examples')
Meteor.startup(() => {
// code to run on server at startup
ExampleCollection.insert({ value: Random.id() })
const docsCursor = ExampleCollection.find();
docsCursor.readPref('primary')
});
Leads to
TypeError: docsCursor.readPref is not a function
The good news is, you can access the layer underneath via Collection.rawCollection()
where you have full access to the node Mongo driver. This is because under the hood Meteor's Mongo.Collection
and it's Cursor
are making use of this native driver in the end.
Now you will find two other issues:
readPref
is named in a node-mongo cursor cursor.setReadPreference (3.1 API).
Cursor.fetch
does not exist but is named cursor.toArray
which (as many native operations do) returns a Promise
you can do the following:
import { Meteor } from 'meteor/meteor';
import { Random } from 'meteor/random';
const ExampleCollection = new Mongo.Collection('examples')
Meteor.startup(() => {
// code to run on server at startup
ExampleCollection.insert({ value: Random.id() })
const docsCursor = ExampleCollection.rawCollection().find();
docsCursor.setReadPreference('primary')
docsCursor.toArray().then((docs) => {
console.log(docs)
}).catch((err)=> console.error(err))
});
By using collection.rawCollection()
you an have access to the full spectrum of the node mongo driver API
You are on your own to integrate the operations, cursors and results (Promises) into your environment. Good helpers are Meteor.bindEnvironment and Meteor.wrapAsync
Beware of API changes of the node-mongo driver. On the one hand the mongo version that is supported by the driver, on the other hand the driver version that is supported by Meteor.
Note that it is easier to "mess up" things with the native API but it also gives you a lot of new options. Use with care.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With