【问题标题】:retrieve mongoDB driver db from mongoose从 mongoose 检索 mongoDB 驱动程序数据库
【发布时间】:2019-09-06 12:01:42
【问题描述】:

我正在设计一个模块,它提供了一个构造函数,该函数接受一个 mongo db 实例作为其参数。在我的应用程序中,我正在尝试使用猫鼬对此进行测试。由于 mongoose 是基于 mongoDB 驱动模块构建的,我假设有一种方法可以从 mongoose 模块中检索 db 驱动对象。

我有一个失败的功能,但我不确定原因。

更新

下面是我模块中的代码

//authorizer.js
function Authorizer(mongoDBCon, userOptions){
    this.db = mongoDBCon;
    this.authorize = authorize;
    this.assignOwner = assignOwner;
    this.setUserPermission = setUserPermission;
    this.setRolePermission = setRolePermission;
    this.retrieveUserPermission = retrieveUserPermission;
    this.setRolePermission = setRolePermission;

    let defaultOptions = {
        unauthorizedHandler: (next)=>{
            let error = new Error('user has performed an unauthorized action');
            error.status = 401;
            next(error);
        },
        userAuthCollection: 'user_authorization',
        roleAuthCollection: 'role_authorization',

    }

    this.options = _.assign({},defaultOptions,userOptions);
}

function setRolePermission(role, resource, permissions) {
    let document = {
        role: role,
        resource: resource,
        permissions: permissions,
    };

    //add the document only if the role permission is not found
    let collection = this.db.collection(this.options.roleAuthCollection);
    collection.findOne(document)
        .then((result)=>console.log('in here')) //------> not printing :(
        .catch(e=>{console.log(e)});
}

需要导入/需要在另一个文件中配置

//authorizerConfig
let mongoose = require('mongoose');
let Authorizer = require('util/authorization/authorization');

let authorizer = new Authorizer(mongoose.connection.db);

//set admin role permissions
authorizer.setRolePermission('admin', 'users', '*');
authorizer.setRolePermission('admin', 'postings', '*');

module.exports = authorizer;

连接到 mongo 的文件

//app.js
// Set up and connect to MongoDB:
const mongoose = require('mongoose');
mongoose.Promise = Promise;
mongoose.connect(process.env.MONGODB_URI);//MONGODB_URI=localhost:27017/house_db

我现在没有看到我希望在 then() 方法中看到的日志。

  1. mongoose.connection.db 是否等同于返回的 db 实例 来自 MongoClient.connect ?
  2. mongoClient 不支持承诺吗?
  3. 您能帮我解决问题吗?

答案: @Neil Lunn 为我提供了答案。综上所述,mongoose.connection.db就相当于MongoClient.connect返回的db。另外,我遇​​到了一个错误,因为我在建立连接之前查询了数据库。

【问题讨论】:

  • 但据我所知,这个构造函数如何知道 this.db 是什么并找到它的功能。发布您的完整代码,您将如何实现它。如果你完全依赖 mongodb 原生模块或者选择 mongoose,它也会很棒。
  • @rxysm 不需要。尼尔伦恩回答了我的问题。他似乎明白了我的问题。

标签: node.js mongodb mongoose


【解决方案1】:

请注意,这似乎在某些时候发生了变化,在 v5 中我可以像这样访问数据库:

const res = await mongoose.connect(...);
const { db } = mongoose.connection;
const result = await db.collection('test').find().toArray();

【讨论】:

    【解决方案2】:

    使用 connection 对象检索 MongoDB 驱动程序实例。

    const mongoose = require('mongoose');
    mongoose.connect('mongodb://localhost:27017/testdb', function (err){
        if (err) throw err;
        let db = mongoose.connection.db; // <-- This is your MongoDB driver instance.
    });
    

    【讨论】:

    • mongoose.connection.db 给出未定义
    • @user3003976 确保在连接成功后使用它。
    • 对我来说是:const collection = mongoose.connection.client.db(dbName).collection(collectionName);
    【解决方案3】:

    MongoClient 和底层节点驱动当然支持 Promise。这只是因为您没有通过您实际使用的任何方法引用正确的“数据库对象”。

    作为演示:

    const mongoose = require('mongoose'),
          Schema = mongoose.Schema;
    
    mongoose.Promise = global.Promise;
    mongoose.set('debug',true);
    
    const uri = 'mongodb://localhost/other',    // connect to one database namespace
          options = { useMongoClient: true };
    
    function log(data) {
      console.log(JSON.stringify(data,undefined,2))
    }
    
    (async function() {
    
      try {
    
        const conn = await mongoose.connect(uri,options);
    
        const testDb = conn.db.db('test');  // For example,  get "test" as a sibling
    
        let result = await testDb.collection('test').find().toArray();
        log(result);
    
      } catch(e) {
        console.error(e);
      } finally {
        mongoose.disconnect();
      }
    
    })();
    

    所以你“应该”做的是从连接中获取"connection" 对象,并从中引用db。您可能需要当前连接的“兄弟”db 空间,在您的特定情况下可能需要 "admin" 来获取“身份验证”详细信息。

    但这里我们使用Db Object 之外的.db() 方法来访问“命名兄弟”。这显然不是异步方法,就像.collection() 不是异步一样。

    从那里开始,只需从核心驱动程序实现相应对象的其他本地方法即可。

    【讨论】:

    • 你完全理解我的问题!让我去测试一下。感谢您的回复
    • 所以我对 `conn.db.db('test');` 的作用有点困惑。在上面的示例中,您的 uri 设置为“mongodb://localhost/other”。因此,您要连接的数据库称为“其他”。 “测试”在这里应该代表什么?兄弟数据库空间是什么意思?这不就是 mongo 应用程序中的另一个数据库吗?
    • @alaboudi "test" 代表“另一个数据库名称”。 所有 MongoDB 安装实际上使用"test" 作为默认命名空间。在您的情况下,答案中提到的“兄弟姐妹”将是 "admin"
    • 所以我刚刚尝试了您的解决方案,我得到了完全相同的结果。我尝试拿走then() 并将链记录到 find() 函数。在这两种情况下,我都会返回一个游标。我从那里去哪里
    • @alaboudi 您实际上并没有在问题中包含您的代码。因此,如果没有看到代码,我无法告诉您它有什么问题。此代码示例有效。因此,如果您的方法不起作用,那么您正在做一些不同的事情。如果您无法弄清楚有什么不同,请“发布您的代码”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-12
    • 2015-09-20
    • 2016-03-13
    • 1970-01-01
    • 2014-07-04
    相关资源
    最近更新 更多