Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to specify read preference in Meteor's mongo queries

Tags:

In Meteor Mongo, how to specify the readPref to primary|secondary in Meteor Mongo Query.

like image 667
Chetan Avatar asked Jul 14 '18 04:07

Chetan


People also ask

What is read preference in MongoDB?

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").

What is staleness in MongoDB?

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.

How do I change primary node in MongoDB?

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.


1 Answers

I hope the following provides a better understanding of the relationship between Meteor and Mongo.


Meteor collections for more comfort

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


Accessing the node mongo driver collections

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:

  1. readPref is named in a node-mongo cursor cursor.setReadPreference (3.1 API).

  2. Cursor.fetch does not exist but is named cursor.toArray which (as many native operations do) returns a Promise


So to finally answer your question

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))
});


Summary

  • 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.

like image 174
Jankapunkt Avatar answered Sep 28 '22 05:09

Jankapunkt