简体   繁体   English

如何使用统一拓扑和承诺从 NodeJS 连接到 MongoDB

[英]How to connect from NodeJS to MongoDB using Unified Topology and Promises

I'm new to MongoDB - sorry in advance for any pebkac.我是 MongoDB 的新手 - 提前为任何 pebkac 感到抱歉。

Per this article , the Unified Topology paradigm moves away from the concept of "connecting" and instead simply sets up a connection string and begins doing operations.根据本文,统一拓扑范式摆脱了“连接”的概念,而是简单地设置连接字符串并开始执行操作。 Each operation then fails or succeeds depending on whether the driver can reach a server at the time that operation is executed.然后,每个操作失败或成功取决于驱动程序在执行该操作时是否可以访问服务器。

I'm trying to implement the following example code to establish a "connection" to a local MongoDB server on my test machine, but it's not working: Node is throwing uncaught Promise Reject messages, apparently because it's erroring out somewhere along the way.我正在尝试实现以下示例代码,以在我的测试机器上建立到本地 MongoDB 服务器的“连接”,但它不起作用:Node 正在抛出未捕获的 Promise Reject 消息,显然是因为它在途中的某个地方出错了。

However, the example code does not show how to implement the new paradigm using Promises.但是,示例代码并未展示如何使用 Promise 实现新范式。 I'm assuming that's the main problem, so I tried the second code shown below, and am still not getting an object that allows me to retrieve records.我假设这是主要问题,所以我尝试了下面显示的第二个代码,但仍然没有得到一个允许我检索记录的对象。 Can you advise what I'm doing wrong, and also the recommended/best way to do this within an Express app to ensure it is as stable as possible?您能否建议我做错了什么,以及在 Express 应用程序中执行此操作的推荐/最佳方法以确保它尽可能稳定?

First attempt: index.js:第一次尝试:index.js:

async function init(){
    console.log("Starting...");
    const MongoClient = require('mongodb');
    const client = MongoClient('mongodb://test:test@localhost:27017', { useUnifiedTopology: true });
    const coll = client.db('test').collection('foo');
    await coll.insert({ test: 'document' });
    const docs = coll.find({ test: 1 }, { readPreference: 'secondary' }).toArray();
    console.dir({ docs });
    await client.close();
}


init();

Errors:错误:

Starting...
(node:15328) UnhandledPromiseRejectionWarning: TypeError: client.db is not a function
    at init (index.js:5:22)
    at Object.<anonymous> (index.js:13:1)
    at Module._compile (internal/modules/cjs/loader.js:1128:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1167:10)
    at Module.load (internal/modules/cjs/loader.js:983:32)
    at Function.Module._load (internal/modules/cjs/loader.js:891:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
    at internal/main/run_main_module.js:17:47
(node:15328) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:15328) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

So obviously this is trying to use Promises, but the example doesn't implement in this way.所以很明显这是在尝试使用 Promises,但这个例子并没有以这种方式实现。

Here's the second attempt:这是第二次尝试:

index.js:索引.js:

async function init(){
    console.log("Starting...");
    const MongoClient = require('mongodb');
    const client = MongoClient('mongodb://test:test@localhost:27017', { useUnifiedTopology: true })
        .then(async (result) => {
            console.log("Connected: result = ", result);

            const db = result('test');  // Get the 'test' database
            const coll = db.collection('foo');  // Ge the 'foo' collection
            await coll.insert( { test: 'document' });   // Create a new document
            const docs = coll.find({}, { readPreference: 'secondary'})  // Retrieve all docs
                .then((results) => {
                    const data = results.toArray();
                    console.log('Results: ', data);
                });
            await client.close();

        })
        .catch((err) => {
            console.log('Caught error: ', err);
        });
}


init();

Output:输出:

Starting...
Connected: result =  MongoClient {
  _events: [Object: null prototype] { newListener: [Function (anonymous)] },
  _eventsCount: 1,
  _maxListeners: undefined,
  s: {
    url: 'mongodb://test:test@localhost:27017',
    options: {
      servers: [Array],
      caseTranslate: true,
      useUnifiedTopology: true,
      checkServerIdentity: true,
      sslValidate: true,
      auth: [Object],
      authSource: 'admin',
      dbName: 'test',
      socketTimeoutMS: 360000,
      connectTimeoutMS: 30000,
      retryWrites: true,
      useRecoveryToken: true,
      readPreference: [ReadPreference],
      credentials: [MongoCredentials],
      promiseLibrary: [Function: Promise]
    },
    promiseLibrary: [Function: Promise],
    dbCache: Map {},
    sessions: Set {},
    writeConcern: undefined,
    namespace: MongoDBNamespace { db: 'admin', collection: undefined }
  },
  topology: NativeTopology {
    _events: [Object: null prototype] {
      authenticated: [Function (anonymous)],
      error: [Function (anonymous)],
      timeout: [Function (anonymous)],
      close: [Function (anonymous)],
      parseError: [Function (anonymous)],
      fullsetup: [Function],
      all: [Function],
      reconnect: [Function (anonymous)],
      serverOpening: [Function (anonymous)],
      serverDescriptionChanged: [Function (anonymous)],
      serverHeartbeatStarted: [Function (anonymous)],
      serverHeartbeatSucceeded: [Function (anonymous)],
      serverHeartbeatFailed: [Function (anonymous)],
      serverClosed: [Function (anonymous)],
      topologyOpening: [Function (anonymous)],
      topologyClosed: [Function (anonymous)],
      topologyDescriptionChanged: [Function (anonymous)],
      commandStarted: [Function (anonymous)],
      commandSucceeded: [Function (anonymous)],
      commandFailed: [Function (anonymous)],
      joined: [Function (anonymous)],
      left: [Function (anonymous)],
      ping: [Function (anonymous)],
      ha: [Function (anonymous)]
    },
    _eventsCount: 24,
    _maxListeners: Infinity,
    s: {
      id: 0,
      options: [Object],
      seedlist: [Array],
      state: 'connected',
      description: [TopologyDescription],
      serverSelectionTimeoutMS: 30000,
      heartbeatFrequencyMS: 10000,
      minHeartbeatFrequencyMS: 500,
      Cursor: [Function: Cursor],
      bson: BSON {},
      servers: [Map],
      sessionPool: [ServerSessionPool],
      sessions: Set {},
      promiseLibrary: [Function: Promise],
      credentials: [MongoCredentials],
      clusterTime: null,
      iterationTimers: Set {},
      connectionTimers: Set {},
      clientInfo: [Object]
    }
  }
}

Caught error:  TypeError: result is not a function
    at index.js:8:15
    at processTicksAndRejections (internal/process/task_queues.js:97:5)

Here's a full example of connecting to the MongoDB database from Node.JS using the Unified Topology paradigm (no explicit connect commands).这是使用统一拓扑范例(无显式connect命令)从 Node.JS 连接到 MongoDB 数据库的完整示例。 Thanks to @MaheshBhatnagar for pointing out my mistake.感谢@MaheshBhatnagar 指出我的错误。

This example uses Promises, and after setting up the connection, begins inserting records at a frequency of one every 5 seconds.此示例使用 Promises,并在建立连接后开始以每 5 秒一条的频率插入记录。 If you disable or disconnect the MongoDB database, it will cache the inserts until either (a. it times out, default of 30 seconds, or b. the connection is restored).如果禁用或断开 MongoDB 数据库,它将缓存插入直到(a. 超时,默认为 30 秒,或 b. 连接恢复)。 If it times out, the inserts will be lost, but if the server is brought back online, subsequent requests will be handled properly.如果超时,插入将丢失,但如果服务器重新联机,后续请求将得到正确处理。

Let me know if I am doing this wrong, or any suggestions.如果我做错了,请告诉我,或任何建议。

index.js:索引.js:

const url = 'mongodb://test:test@localhost:27017';


async function init(){
    console.log("init...");
    const MongoClient = require('mongodb');

    return MongoClient(url, { useUnifiedTopology: true}); // Return a Promise
}


async function go(db_result) {
    // Do an insert and output the last-inserted document.
    console.log("Go...");

    const db = db_result.db('test');  // Get the 'test' database
    const coll = db.collection('foo');  // Ge the 'foo' collection
    // Create a new document:
    await coll.insertOne({ test: 'document' }, (err, response) => {
        if (err) {
            console.log("Error inserting", err);
        }
        else
        {
            console.log("New record: ", response.ops[0])  // Output newly inserted record (thanks to https://stackoverflow.com/questions/40766654)
        }
    });   


}

// Sleep for a specified time:
function sleep(ms) {
    return new Promise( resolve => {
        setTimeout(resolve,ms)
    })
}


init()  // Set up connection, then start doing inserts.
    .then( async (db_result) => {
        // When MongoClient is instantiated:
        while(true) {
            console.log("Going...")
            go(db_result)
            console.log("Sleeping")
            await sleep(5000);
        }
    })
    .catch((err) => {
        console.log("Caught error: ", err)
    })

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM