如何为MongoDB指定查询设置Read Preference?附Mongoose Node.js示例
Mongoose 环境下为MongoDB查询设置Read Preference指南
可选Read Preference模式说明
你可以根据业务对数据一致性、可用性的要求选择对应模式:
primary:默认值,仅从主节点读取,主节点不可用时直接报错,适合强一致性要求的场景primaryPreferred:优先读取主节点,主节点不可用时自动切到从节点读取secondary:仅从从节点读取,所有从节点不可用时报错,适合可以容忍少量同步延迟的只读场景,可分担主节点压力secondaryPreferred:优先读取从节点,无可用从节点时自动切到主节点读取nearest:从网络延迟最低的节点读取,不区分主从,适合跨区域部署的集群场景
单查询指定Read Preference(推荐,不影响全局配置)
find 查询示例
支持两种写法,链式调用可读性更高:
const User = require('./models/User'); // 替换为你自己定义的Mongoose模型 // 写法1:链式调用read方法指定 async function queryUsers() { return await User.find({ age: { $gte: 18 } }) .select('name age email') // 指定返回字段 .read('secondaryPreferred') // 这里设置读偏好 .exec(); } // 写法2:在find方法的options参数中指定 async function queryUsers2() { return await User.find( { age: { $gte: 18 } }, // 查询条件 { name: 1, age: 1, email: 1 }, // 字段投影 { readPreference: 'secondaryPreferred' } // 读偏好配置 ); }
aggregate 查询示例
和find查询类似,同样支持链式调用和参数配置两种写法:
// 写法1:链式调用 async function aggregateUserStats() { return await User.aggregate([ { $match: { age: { $gte: 18 } } }, { $group: { _id: '$city', userCount: { $sum: 1 } } }, { $sort: { userCount: -1 } } ]) .read('secondary') // 指定仅从从节点执行聚合查询 .exec(); } // 写法2:参数配置 async function aggregateUserStats2() { return await User.aggregate( [/* 聚合管道逻辑 */], { readPreference: 'secondary' } // 读偏好配置 ); }
全局默认配置(可选)
如果要让所有查询默认使用同一个Read Preference,可以在建立数据库连接时指定,单查询的单独配置优先级高于全局配置:
const mongoose = require('mongoose'); mongoose.connect('mongodb://你的MongoDB集群地址/数据库名?replicaSet=副本集名称', { readPreference: 'secondaryPreferred' // 全局默认读偏好 });
注意:如果你的查询对数据一致性要求极高(比如写入后立即可读的场景),建议使用
primary模式,避免从节点同步延迟导致读取到旧数据。
内容的提问来源于stack exchange,提问作者Yogesh Barot
相关产品推荐
相关产品推荐

