如何在 Meteor 的 mongo 查询中指定读取偏好

Che*_*tan 5 mongodb meteor

在 Meteor Mongo 中,如何在 Meteor Mongo Query 中将 readPref 指定为 primary|secondary。

Jan*_*nkt 4

希望下面的内容能让大家更好的理解Meteor和Mongo的关系。


Meteor系列更舒适

Meteor 为您提供完整的 mongo 功能。然而,为了方便起见,它提供了mongo 集合的封装 API,与 Meteor 环境集成得最好。所以如果你通过导入 Mongo

import { Mongo } from 'meteor/mongo' 
Run Code Online (Sandbox Code Playgroud)

您主要导入包装好的 mongo 集合,其中的操作在 Meteor Fiber 中执行。这些包装集合的查询返回的游标也不是“自然”游标,而是要进行 Meteor 优化的包装游标

如果您尝试访问这些实例上未实现的本机功能,您将收到错误。在你的情况下:

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')
}); 
Run Code Online (Sandbox Code Playgroud)

导致

TypeError: docsCursor.readPref is not a function
Run Code Online (Sandbox Code Playgroud)


访问节点 mongo 驱动程序集合

好消息是,您可以通过对节点 Mongo 驱动程序具有完全访问权限来访问底层。Collection.rawCollection()这是因为 MeteorMongo.Collection和它Cursor最终都在使用这个原生驱动程序。

现在你会发现另外两个问题:

  1. readPref在node-mongo游标中命名为cursor.setReadPreference(3.1 API)。

  2. Cursor.fetch不存在,但被命名cursor.toArray为(与许多本机操作一样)返回 Promise


所以最后回答你的问题

您可以执行以下操作:

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))
});
Run Code Online (Sandbox Code Playgroud)


概括

  • 通过使用collection.rawCollection()您可以访问所有节点mongo 驱动程序 API

  • 您需要自行将操作、光标和结果(Promises)集成到您的环境中。好帮手是Meteor.bindEnvironmentMeteor.wrapAsync

  • 请注意 Node-mongo 驱动程序的 API 更改。一方面是驱动支持的mongo版本,另一方面是Meteor支持的驱动版本。

  • 请注意,使用本机 API 更容易“搞乱”事情,但它也为您提供了很多新选项。小心使用。