Узел.запросы async/await драйвера JS mongodb

У меня есть узел.приложение js с использованием собственного драйвера mongodb. В процессе миграции моего кода приложения на async / await с помощью узла v8.9.1, я изо всех сил пытаюсь найти элегантный способ для запросов mongodb. Основная проблема с драйвером mongodb заключается в том, что все запросы используют обратные вызовы, где функции обещаний обязательны для асинхронных методов.

альтернативы: мангуста - обещает запросы устарели, и это заставляет использовать модель схемы, которая немного накладные расходы для моего приложения. mongoist- якобы здорово, так как он построен с асинхронным/ожиданием в виду и полностью обещает, но ошибки с SSL - подключением к mongodb и плохая документация-отвлекли меня от этого решения.

единственным обходным путем, который мне удалось реализовать элегантным способом, является использование обратный вызов-обещание пакет npm для преобразования MongoDB driver API в полное обещание.

любые свежие идеи для элегантного пути высокой эффективности?

6 ответов


Edit: 'mongodb'В3.x

по данным MongoDB в ES6 в будущем проверьте этот фрагмент кода;

let MongoClient = require('mongodb').MongoClient;
const connectionString = 'mongodb://localhost:27017';

    (async () => {
        let client = await MongoClient.connect(connectionString,
            { useNewUrlParser: true });

        let db = client.db('dbName');
        try {
           const res = await db.collection("collectionName").updateOne({ 
               "someKey": someValue
           }, { $set: someObj }, { upsert: true });

           console.log(`res => ${JSON.stringify(res)}`);
        }
        finally {
            client.close();
        }
    })()
        .catch(err => console.error(err));

спасибо. Отлично работает с ES6:

const middleWare = require('middleWare');
const MONGO = require('mongodb').MongoClient;

router.get('/', middleWare(async (req, res, next) => {
    const db = await MONGO.connect(url);
    const MyCollection = db.collection('MyCollection');
    const result = await MyCollection.find(query).toArray();
    res.send(result);
}))

Если вы не передаете обратный вызов, клиент mongodb возвращает обещание.

официальный узел MongoDB.драйвер js обеспечивает как обратный вызов, так и обещанное взаимодействие с MongoDB, позволяя приложениям в полной мере использовать новые функции в ES6

с официального docs


Я отправляю это как ответ, потому что я не могу комментировать ответ Идо Льва. Я перенесу это, как только достигну 50 репутации.

Не забудьте закрыть соединение с БД. В противном случае возможно, что ваше приложение не может подключиться к БД из-за слишком большого количества открытых соединений (случилось со мной неделю назад).

ваш запрос может быть успешным или неудачным, поэтому имеет смысл закрыть соединение в finally-блок.

const db = await MongoClient.connect(url);
try {
    const stuff = await db.collection("Stuff").find({});
    // Do something with the result of the query
} finally {
    db.close();
}

обновление: похоже, что это не решит мою проблему. Некоторые люди говорят, что вам даже не нужно закрывать соединение вручную. Кажется, что лучше всего повторно использовать соединение через приложение, если это возможно.


Мангуст найти запрос с помощью async / await

не используйте mongoose.connect в случае async / await

    var router = require("express").Router()
    var mongoose = require("mongoose")
var await = require("await")
var async = require("async")

    var mongoUrl = "mongodb://localhost:27017/ekaushalnsdc"

    router.get("/async/await/find",async(req, res,  next) => {
      try {
        var db =  await mongoose.createConnection(mongoUrl)
          var colName = db.collection('collectionName')
        var result  = await colName.find({}).toArray()
        res.json(result)
    }catch(ex) {
       res.json(ex.message)
    }
    })

...но если вы хотите работать с курсором без выгрузки в массив, вы не можете использовать await с функциями find() или aggregate (), тогда вам нужно использовать код:

const cursor = db.collection('name').aggregate(
    [
        {
            "$match": {code: 10}
        },
        {
          "$count": "count"
        }
    ],
    {
        "allowDiskUse": false
    }
)

for (let doc = await cursor.next(); doc != null; doc = await cursor.next()) {
    console.log('aggregate:', doc.count);
}