【问题标题】:Cant read data from collection in MongoDB Atlas Trigger无法从 MongoDB Atlas 触发器中的集合中读取数据
【发布时间】:2021-11-15 14:35:51
【问题描述】:

MongoDB 的新手,Atlas 的新手。我正在尝试设置一个触发器,以便它从名为Config 的集合中读取所有数据。这是我的尝试:

exports = function(changeEvent) {
  const mongodb = context.services.get("Cluster0");
  const db = mongodb.db("TestDB");
  var collection = db.collection("Config");
  config_docs = collection.find().toArray(); 
  console.log(JSON.stringify(config_docs));
}

该函数是名为Triggers_RealmApp 的自动创建领域应用程序的一部分,该应用程序将Cluster0 作为命名的链接数据源。当我进入 Cluster0 中的集合时,TestDB.Config 是集合之一。

一些注意事项:

  • 不是抛出错误,而是简单地返回{}
  • 当我将 context.services.get("Cluster0"); 更改为其他内容时,它会引发错误
  • 当我将"TestDB" 更改为不存在的数据库,或将"Config" 更改为不存在的集合时,我得到相同的输出; {}
  • 我尝试过创建新的 Realm 应用程序、手动创建服务、创建新数据库和新集合等。我一直遇到同样的问题。
  • mongo 文档引用了 promises 和 awaits,我在任何示例中都没有看到 (link)。我试着尝试了一下,但一无所获。据我所知,我已经做的是典型的做法。

图片: 收藏: 关联数据源:

【问题讨论】:

    标签: javascript mongodb mongodb-atlas


    【解决方案1】:

    您可以使用mongodb.MongoClient 轻松完成此操作。您的连接字符串包含您想要的集群名称。您可以选择任何数据库和集合。

    import { MongoClient } from 'mongodb'
    
    module.exports = function(changeEvent) {
        const uri = 'your connection uri'
        const options = {
            useUnifiedTopology: true,
            useNewUrlParser: true,
        }
        
        const client = new MongoClient(uri, options)
        client.on('open', _=> console.log('DB connected successfully(mongo)'))
        client.on('error', _=> console.log('Ooopppss. Could not connect to database'))
        client.on('topologyClosed', _=> console.log('DB has been disconnected'))
        
        await client.connect()
        
        const config_docs = await client
            .db('TestDB')
            .collection("Config")
            .find({})   // <-
            .sort({ metacritic: -1 })
            .limit(20)
            .toArray();
        console.log(config_docs)
    }
    

    【讨论】:

    • 我直接在 MongoDB Atlas 函数中工作,所以不需要创建 URI 对吧?这似乎更像是一种 hack 而不是解决方案。
    • 我不知道为什么会如此受欢迎。绝对不建议使用 MongoDB 客户端作为 atlas 中的触发器。
    【解决方案2】:

    我最终直接使用 MongoDB,.find() 是异步的,我处理不正确。这是马口中的直接回复:


    据我了解,您没有从上面发布的查询中获得预期的结果。我知道当您刚开始使用新技术并且无法使某些东西发挥作用时,这可能会令人困惑!

    问题在于 collection.find() 函数是一个异步函数。这意味着它发出请求但在继续之前不等待回复。相反,它返回一个 Promise,它是一个描述操作当前状态的对象。由于 Promise 确实不是数组,因此您的声明 collection.find().toArray() 将返回一个空对象。您将这个空对象写入 console.log 并结束您的函数,可能在异步调用甚至返回您的数据之前。

    有几种方法可以解决这个问题。首先是让你的函数成为异步函数,并使用 await 运算符告诉你的函数等待 collection.find() 函数返回,然后再继续。

    exports = async function(changeEvent) {
      const mongodb = context.services.get("Cluster0");
      const db = mongodb.db("TestDB");
      var collection = db.collection("Config");
      config_docs = await collection.find().toArray(); 
      console.log(JSON.stringify(config_docs));
    
    };
    

    注意第一行的 async 关键字,以及倒数第二行的 await 关键字。

    第二种方法是使用.then函数在结果返回时进行处理:

    exports = function(changeEvent) {
      const mongodb = context.services.get("Cluster0");
      const db = mongodb.db("TestDB");
      var collection = db.collection("Config");
      collection.find().toArray().then(config_docs => {
        console.log(JSON.stringify(config_docs));
      });
    };
    

    【讨论】:

      【解决方案3】:

      连接必须是到主副本集的连接,并且用户登录凭据是管理员级别的用户(需要具有集群管理员的权限)

      【讨论】:

        猜你喜欢
        • 2019-09-15
        • 2019-12-22
        • 1970-01-01
        • 1970-01-01
        • 2015-02-11
        • 2020-02-29
        • 2017-05-15
        • 2021-12-20
        • 2012-06-04
        相关资源
        最近更新 更多